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) +================= + +[![Build Status](https://travis-ci.org/bkimminich/esapi-java-legacy.svg?branch=master)](https://travis-ci.org/bkimminich/esapi-java-legacy) +[![Coverage Status](https://coveralls.io/repos/github/bkimminich/esapi-java-legacy/badge.svg?branch=develop)](https://coveralls.io/github/bkimminich/esapi-java-legacy?branch=develop) +[![Coverity Status](https://scan.coverity.com/projects/8517/badge.svg)](https://scan.coverity.com/projects/bkimminich-esapi-java-legacy) +[![OpenSSF Best Practices](https://bestpractices.coreinfrastructure.org/projects/137/badge)](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 - - - - -

Welcome to ESAPI

- -

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:

- -
java -Dorg.owasp.esapi.resources="/path/to/resources/directory"
- -

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: - -
validation.isValidDataFromBrowser( "Email", input );
- -Or - -
-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:

+
    +
  1. 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.

    +
  2. 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?

    +
  3. 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.

    +
  4. 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.)

    +
  5. 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: +

+ + + + + + + + + + + +
+

Original Tux image

+
+

Tux image encrypted using ECB mode

+
+

Tux image encrypted with other modessuch as CBC

+
+

Original Tux image

+
+

Image encrypted using ECB mode

+
+

Image encrypted using modes other than ECB

+
+

Ciphertext encrypted with ECB cipher mode are also subject to +"block replay attacks". See Bruce Schneier's Applied +Cryptography: protocols, algorithms, and source code for +details. +

+

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:

+
    +
  1. 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.

    +
  2. 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?

    +
  3. Because the reference implementation in JavaEncryptor + allows no means to specify an Initialization Vector (IV), only the + weak ECB cipher mode can be used.

    +
  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.

    +
+

The Encryption Changes in ESAPI 2.0-rc3 and Later

+

Briefly speaking, the changes being implemented for ESAPI Java 2.0 +are: +

+
    +
  1. 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.

    +
  2. 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.

    +
  3. 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.) +

    +
  4. 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:

+ +


+

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Original input length of plaintext
(# + bytes)

+
+

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: +

+
CipherText encrypt(SecretKey key, PlainText plaintext)
+        throws EncryptionException;

+and +

+
PlainText decrypt(SecretKey key, CipherText ciphertext)
+        throws EncryptionException

+(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:

+
String encrypt(String plaintext) throws EncryptionException

+and +

+
String decrypt(String ciphertext) throws EncryptionException

+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

+
String decrypt(String ciphertext) throws EncryptionException

+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. +

+
    String myplaintext = "My plaintext";
+    try {
+        String ciphertext = ESAPI.encryptor().encrypt(myplaintext);
+        String decrypted  = ESAPI.encryptor().decrypt(ciphertext);
+        assert decrypted.equals(myplaintext);
+    } catch(EncryptionException ex) {
+        // Log error then return error designation however appropriate
+    }

+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: +

    +
  1. +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. +
  2. +
  3. +If parties are only exchanging raw ciphertext (plus IV, when appropriate), +then they must also agree on the cipher transformation to use. +
  4. +
  5. +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. +
  6. +
+

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: +

+
    String myplaintext = "My plaintext";
+    try {
+        CipherText ciphertext =
+            ESAPI.encryptor().encrypt( new PlainText(myplaintext) );
+        PlainText recoveredPlaintext = ESAPI.encryptor().decrypt(ciphertext) );
+        assert myplaintext.equals( recoveredPlaintext.toString() );
+    } catch(EncryptionException ex) {
+        // Log error then return error designation however appropriate.
+    }

+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 authenticity and +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:

+
+    try {
+        byte[] plaintextByteArray = { /* byte array to be encrypted */ };
+        CipherText ciphertext =
+            ESAPI.encryptor().encrypt( new PlainText(plaintextByteArray) );
+        PlainText recoveredPlaintext = ESAPI.encryptor().decrypt(ciphertext) );
+
+        assert java.util.Arrays.equals( plaintextByteArray,
+                                        recoveredPlaintext.asBytes() );
+    } catch(EncryptionException ex) {
+        // Log error then return error designation however appropriate.
+    }
+

+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.) +

+
    // Generate two random, 128-bit AES keys to be distributed out-of-band.
+    import javax.crypto.SecretKey;
+    import org.owasp.esapi.crypto.CryptoHelper;
+    import org.owasp.esapi.codecs.Hex;
+
+    public class MySecretKeys {
+        public void main(String[] args) {
+          try {
+            SecretKey bankAcctKey = CryptoHelper.generateSecretKey("AES", 128);
+            SecretKey credCardKey = CryptoHelper.generateSecretKey("AES", 128);
+
+            System.out.println("Bank account key: " +
+                Hex.encode( bankAcctKey.getEncoding(), true ) );
+            System.out.println("Credit card key: " +
+                Hex.encode( credCardKey.getEncoding(), true ) );
+          } catch(Exception ex) {
+            ex.printStackTrace(System.err);
+            System.exit(1);
+          }
+          System.exit(0);
+        }
+    }

+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: +

+		ESAPI.securityConfiguration().setCipherTransformation(cipherXform);
+
+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.) +
+
    +
  1. 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. +
  2. +
  3. 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.) +
  4. +
  5. 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.) +
  6. +
  7. 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. +
  8. +
  9. +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(). +
  10. +
+
+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 "&#37;" (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 "&amp;" 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 -
- - - - - -
AccessControlException -
-AccessController -
-AccessControllerTest -
-AccessReferenceMap -
-AccessReferenceMapTest -
-AllTests -
-AuthenticationAccountsException -
-AuthenticationCredentialsException -
-AuthenticationException -
-AuthenticationHostException -
-AuthenticationLoginException -
-Authenticator -
-AuthenticatorTest -
-AvailabilityException -
-Base64 -
-Base64.InputStream -
-Base64.OutputStream -
-CSSCodec -
-CertificateException -
-Codec -
-DefaultEncoder -
-DefaultEncryptedProperties -
-DefaultExecutor -
-DefaultHTTPUtilities -
-DefaultIntrusionDetector -
-DefaultRandomizer -
-DefaultSecurityConfiguration -
-DefaultUser -
-DefaultValidator -
-ESAPI -
-ESAPIFilter -
-ESAPIFilterTest -
-ESAPITest -
-EncodeForHTMLAttributeTag -
-EncodeForHTMLJavaScriptTag -
-EncodeForHTMLTag -
-EncodeForVBScriptTag -
-Encoder -
-EncoderTest -
-EncodingException -
-EncryptedProperties -
-EncryptedPropertiesTest -
-EncryptionException -
-Encryptor -
-EncryptorTest -
-EnterpriseSecurityException -
-EnterpriseSecurityExceptionTest -
-Executor -
-ExecutorException -
-ExecutorTest -
-FileBasedAccessController -
-FileBasedAuthenticator -
-HTMLEntityCodec -
-HTTPUtilities -
-HTTPUtilitiesTest -
-IntegerAccessReferenceMap -
-IntegerAccessReferenceMapTest -
-IntegrityException -
-IntrusionDetector -
-IntrusionDetectorTest -
-IntrusionException -
-JavaEncryptor -
-JavaLogFactory -
-JavaScriptCodec -
-LogFactory -
-Logger -
-LoggerTest -
-MySQLCodec -
-OracleCodec -
-PercentCodec -
-PushbackString -
-RandomAccessReferenceMap -
-Randomizer -
-RandomizerTest -
-SafeFile -
-SafeFileTest -
-SafeHTTPFilter -
-SafeRequest -
-SafeResponse -
-SecurityConfiguration -
-SecurityConfiguration.Threshold -
-StringUtilities -
-TestFilterChain -
-TestHttpServletRequest -
-TestHttpServletResponse -
-TestHttpSession -
-TestRequestDispatcher -
-TestServletInputStream -
-User -
-UserTest -
-VBScriptCodec -
-ValidationAvailabilityException -
-ValidationErrorList -
-ValidationException -
-ValidationUploadException -
-Validator -
-ValidatorTest -
-
- - - diff --git a/javadoc/allclasses-noframe.html b/javadoc/allclasses-noframe.html deleted file mode 100644 index 9f09de9b9..000000000 --- a/javadoc/allclasses-noframe.html +++ /dev/null @@ -1,222 +0,0 @@ - - - - - - -All Classes - - - - - - - - - - -All Classes -
- - - - - -
AccessControlException -
-AccessController -
-AccessControllerTest -
-AccessReferenceMap -
-AccessReferenceMapTest -
-AllTests -
-AuthenticationAccountsException -
-AuthenticationCredentialsException -
-AuthenticationException -
-AuthenticationHostException -
-AuthenticationLoginException -
-Authenticator -
-AuthenticatorTest -
-AvailabilityException -
-Base64 -
-Base64.InputStream -
-Base64.OutputStream -
-CSSCodec -
-CertificateException -
-Codec -
-DefaultEncoder -
-DefaultEncryptedProperties -
-DefaultExecutor -
-DefaultHTTPUtilities -
-DefaultIntrusionDetector -
-DefaultRandomizer -
-DefaultSecurityConfiguration -
-DefaultUser -
-DefaultValidator -
-ESAPI -
-ESAPIFilter -
-ESAPIFilterTest -
-ESAPITest -
-EncodeForHTMLAttributeTag -
-EncodeForHTMLJavaScriptTag -
-EncodeForHTMLTag -
-EncodeForVBScriptTag -
-Encoder -
-EncoderTest -
-EncodingException -
-EncryptedProperties -
-EncryptedPropertiesTest -
-EncryptionException -
-Encryptor -
-EncryptorTest -
-EnterpriseSecurityException -
-EnterpriseSecurityExceptionTest -
-Executor -
-ExecutorException -
-ExecutorTest -
-FileBasedAccessController -
-FileBasedAuthenticator -
-HTMLEntityCodec -
-HTTPUtilities -
-HTTPUtilitiesTest -
-IntegerAccessReferenceMap -
-IntegerAccessReferenceMapTest -
-IntegrityException -
-IntrusionDetector -
-IntrusionDetectorTest -
-IntrusionException -
-JavaEncryptor -
-JavaLogFactory -
-JavaScriptCodec -
-LogFactory -
-Logger -
-LoggerTest -
-MySQLCodec -
-OracleCodec -
-PercentCodec -
-PushbackString -
-RandomAccessReferenceMap -
-Randomizer -
-RandomizerTest -
-SafeFile -
-SafeFileTest -
-SafeHTTPFilter -
-SafeRequest -
-SafeResponse -
-SecurityConfiguration -
-SecurityConfiguration.Threshold -
-StringUtilities -
-TestFilterChain -
-TestHttpServletRequest -
-TestHttpServletResponse -
-TestHttpSession -
-TestRequestDispatcher -
-TestServletInputStream -
-User -
-UserTest -
-VBScriptCodec -
-ValidationAvailabilityException -
-ValidationErrorList -
-ValidationException -
-ValidationUploadException -
-Validator -
-ValidatorTest -
-
- - - diff --git a/javadoc/constant-values.html b/javadoc/constant-values.html deleted file mode 100644 index 43f19ecb7..000000000 --- a/javadoc/constant-values.html +++ /dev/null @@ -1,298 +0,0 @@ - - - - - - -Constant Field Values - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Constant Field Values

-
-
-Contents - - - - - - -
-org.owasp.*
- -

- - - - - - - - - - - - -
org.owasp.esapi.HTTPUtilities
-public static final java.lang.StringREMEMBER_TOKEN_COOKIE_NAME"ESAPIRememberToken"
- -

- -

- - - - - - - - - - - - - - - - - - - - - - - - - - - -
org.owasp.esapi.Logger
-public static final java.lang.StringFUNCTIONALITY"FUNCTIONALITY"
-public static final java.lang.StringPERFORMANCE"PERFORMANCE"
-public static final java.lang.StringSECURITY"SECURITY"
-public static final java.lang.StringUSABILITY"USABILITY"
- -

- -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
org.owasp.esapi.codecs.Base64
-public static final intDECODE0
-public static final intDONT_BREAK_LINES8
-public static final intENCODE1
-public static final intGZIP2
-public static final intNO_OPTIONS0
-public static final intORDERED32
-public static final intURL_SAFE16
- -

- -

- - - - - - - - - - - - - - - - - -
org.owasp.esapi.codecs.MySQLCodec
-public static final intANSI_MODE1
-public static final intMYSQL_MODE0
- -

- -

- - - - - - - - - - - - -
org.owasp.esapi.reference.DefaultSecurityConfiguration
-public static final java.lang.StringRESOURCE_DIRECTORY"org.owasp.esapi.resources"
- -

- -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/deprecated-list.html b/javadoc/deprecated-list.html deleted file mode 100644 index 35267c2b1..000000000 --- a/javadoc/deprecated-list.html +++ /dev/null @@ -1,134 +0,0 @@ - - - - - - -Deprecated List - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Deprecated API

-
-
- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/help-doc.html b/javadoc/help-doc.html deleted file mode 100644 index 7e470b55a..000000000 --- a/javadoc/help-doc.html +++ /dev/null @@ -1,193 +0,0 @@ - - - - - - -API Help - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-How This API Document Is Organized

-
-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. - -
-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/index-files/index-1.html b/javadoc/index-files/index-1.html deleted file mode 100644 index 22b859fd7..000000000 --- a/javadoc/index-files/index-1.html +++ /dev/null @@ -1,368 +0,0 @@ - - - - - - -A-Index - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
-

-A

-
-
ANONYMOUS - -Static variable in interface org.owasp.esapi.User -
The ANONYMOUS user is used to represent an unidentified user. -
ANSI_MODE - -Static variable in class org.owasp.esapi.codecs.MySQLCodec -
  -
AccessControlException - exception org.owasp.esapi.errors.AccessControlException.
An AccessControlException should be thrown when a user attempts to access a - resource that they are not authorized for.
AccessControlException(String, String) - -Constructor for class org.owasp.esapi.errors.AccessControlException -
Creates a new instance of EnterpriseSecurityException. -
AccessControlException(String, String, Throwable) - -Constructor for class org.owasp.esapi.errors.AccessControlException -
Instantiates a new access control exception. -
AccessController - interface org.owasp.esapi.AccessController.
The IAccessController interface defines a set of methods that can be used in a wide variety of applications to - enforce access control.
AccessControllerTest - class org.owasp.esapi.reference.AccessControllerTest.
The Class AccessControllerTest.
AccessControllerTest(String) - -Constructor for class org.owasp.esapi.reference.AccessControllerTest -
Instantiates a new access controller test. -
AccessReferenceMap - interface org.owasp.esapi.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.
AccessReferenceMapTest - class org.owasp.esapi.reference.AccessReferenceMapTest.
The Class AccessReferenceMapTest.
AccessReferenceMapTest(String) - -Constructor for class org.owasp.esapi.reference.AccessReferenceMapTest -
Instantiates a new access reference map test. -
AllTests - class org.owasp.esapi.AllTests.
The Class AllTests.
AllTests(String) - -Constructor for class org.owasp.esapi.AllTests -
Instantiates a new all tests. -
AuthenticationAccountsException - exception org.owasp.esapi.errors.AuthenticationAccountsException.
An AuthenticationException should be thrown when anything goes wrong during - login or logout.
AuthenticationAccountsException(String, String) - -Constructor for class org.owasp.esapi.errors.AuthenticationAccountsException -
Creates a new instance of EnterpriseSecurityException. -
AuthenticationAccountsException(String, String, Throwable) - -Constructor for class org.owasp.esapi.errors.AuthenticationAccountsException -
Instantiates a new authentication exception. -
AuthenticationCredentialsException - exception org.owasp.esapi.errors.AuthenticationCredentialsException.
An AuthenticationException should be thrown when anything goes wrong during - login or logout.
AuthenticationCredentialsException(String, String) - -Constructor for class org.owasp.esapi.errors.AuthenticationCredentialsException -
Creates a new instance of EnterpriseSecurityException. -
AuthenticationCredentialsException(String, String, Throwable) - -Constructor for class org.owasp.esapi.errors.AuthenticationCredentialsException -
Instantiates a new authentication exception. -
AuthenticationException - exception org.owasp.esapi.errors.AuthenticationException.
An AuthenticationException should be thrown when anything goes wrong during - login or logout.
AuthenticationException(String, String) - -Constructor for class org.owasp.esapi.errors.AuthenticationException -
Creates a new instance of EnterpriseSecurityException. -
AuthenticationException(String, String, Throwable) - -Constructor for class org.owasp.esapi.errors.AuthenticationException -
Instantiates a new authentication exception. -
AuthenticationHostException - exception org.owasp.esapi.errors.AuthenticationHostException.
An AuthenticationHostException should be thrown when there is a problem with - the host involved with authentication, particularly if the host changes unexpectedly.
AuthenticationHostException(String, String) - -Constructor for class org.owasp.esapi.errors.AuthenticationHostException -
Creates a new instance of AuthenticationHostException. -
AuthenticationHostException(String, String, Throwable) - -Constructor for class org.owasp.esapi.errors.AuthenticationHostException -
Instantiates a new authentication exception. -
AuthenticationLoginException - exception org.owasp.esapi.errors.AuthenticationLoginException.
An AuthenticationException should be thrown when anything goes wrong during - login or logout.
AuthenticationLoginException(String, String) - -Constructor for class org.owasp.esapi.errors.AuthenticationLoginException -
Creates a new instance of EnterpriseSecurityException. -
AuthenticationLoginException(String, String, Throwable) - -Constructor for class org.owasp.esapi.errors.AuthenticationLoginException -
Instantiates a new authentication exception. -
Authenticator - interface org.owasp.esapi.Authenticator.
The Authenticator interface defines a set of methods for generating and - handling account credentials and session identifiers.
AuthenticatorTest - class org.owasp.esapi.reference.AuthenticatorTest.
The Class AuthenticatorTest.
AuthenticatorTest(String) - -Constructor for class org.owasp.esapi.reference.AuthenticatorTest -
Instantiates a new authenticator test. -
AvailabilityException - exception org.owasp.esapi.errors.AvailabilityException.
An AvailabilityException should be thrown when the availability of a limited - resource is in jeopardy.
AvailabilityException(String, String) - -Constructor for class org.owasp.esapi.errors.AvailabilityException -
Creates a new instance of AvailabilityException. -
AvailabilityException(String, String, Throwable) - -Constructor for class org.owasp.esapi.errors.AvailabilityException -
Instantiates a new AvailabilityException. -
accessController() - -Static method in class org.owasp.esapi.ESAPI -
  -
actions - -Variable in class org.owasp.esapi.SecurityConfiguration.Threshold -
  -
addCSRFToken(String) - -Method in interface org.owasp.esapi.HTTPUtilities -
Adds the current user's CSRF token (see User.getCSRFToken()) to the URL for purposes of preventing CSRF attacks. -
addCSRFToken(String) - -Method in class org.owasp.esapi.reference.DefaultHTTPUtilities -
  -
addCookie(Cookie) - -Method in class org.owasp.esapi.filters.SafeResponse -
Add a cookie to the response after ensuring that there are no encoded or - illegal characters in the name and name and value. -
addCookie(String, String, int, String, String) - -Method in class org.owasp.esapi.filters.SafeResponse -
Add a cookie to the response after ensuring that there are no encoded or - illegal characters in the name and name and value. -
addCookie(Cookie) - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
addDateHeader(String, long) - -Method in class org.owasp.esapi.filters.SafeResponse -
Add a cookie to the response after ensuring that there are no encoded or - illegal characters in the name. -
addDateHeader(String, long) - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
addDirectReference(Object) - -Method in interface org.owasp.esapi.AccessReferenceMap -
Adds a direct reference to the AccessReferenceMap and generates an associated indirect reference. -
addDirectReference(Object) - -Method in class org.owasp.esapi.reference.IntegerAccessReferenceMap -
Adds a direct reference and a new indirect reference, overwriting any existing values. -
addDirectReference(Object) - -Method in class org.owasp.esapi.reference.RandomAccessReferenceMap -
Adds a direct reference and a new random indirect reference, overwriting any existing values. -
addError(String, ValidationException) - -Method in class org.owasp.esapi.ValidationErrorList -
Adds a new error to list with a unique named context. -
addEvent(String, String) - -Method in interface org.owasp.esapi.IntrusionDetector -
Adds the event to the IntrusionDetector. -
addEvent(String, String) - -Method in class org.owasp.esapi.reference.DefaultIntrusionDetector -
Adds the event to the IntrusionDetector. -
addException(Exception) - -Method in interface org.owasp.esapi.IntrusionDetector -
Adds the exception to the IntrusionDetector. -
addException(Exception) - -Method in class org.owasp.esapi.reference.DefaultIntrusionDetector -
This implementation uses an exception store in each User object to track - exceptions. -
addHeader(String, String) - -Method in class org.owasp.esapi.filters.SafeResponse -
Add a header to the response after ensuring that there are no encoded or - illegal characters in the name and name and value. -
addHeader(String, String) - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
Adds the header. -
addHeader(String, String) - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
addIntHeader(String, int) - -Method in class org.owasp.esapi.filters.SafeResponse -
Add an int header to the response after ensuring that there are no - encoded or illegal characters in the name and name. -
addIntHeader(String, int) - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
addParameter(String, String) - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
Adds the parameter. -
addRole(String) - -Method in interface org.owasp.esapi.User -
Adds a role to an account. -
addRole(String) - -Method in class org.owasp.esapi.reference.DefaultUser -
  -
addRoles(Set) - -Method in interface org.owasp.esapi.User -
Adds a set of roles to an account. -
addRoles(Set) - -Method in class org.owasp.esapi.reference.DefaultUser -
  -
assertAuthorizedForData(String) - -Method in interface org.owasp.esapi.AccessController -
Checks if an account is authorized to access the referenced data. -
assertAuthorizedForData(String) - -Method in class org.owasp.esapi.reference.FileBasedAccessController -
  -
assertAuthorizedForFile(String) - -Method in interface org.owasp.esapi.AccessController -
Checks if an account is authorized to access the referenced file. -
assertAuthorizedForFile(String) - -Method in class org.owasp.esapi.reference.FileBasedAccessController -
  -
assertAuthorizedForFunction(String) - -Method in interface org.owasp.esapi.AccessController -
Checks if an account is authorized to access the referenced function. -
assertAuthorizedForFunction(String) - -Method in class org.owasp.esapi.reference.FileBasedAccessController -
  -
assertAuthorizedForService(String) - -Method in interface org.owasp.esapi.AccessController -
Checks if an account is authorized to access the referenced service. -
assertAuthorizedForService(String) - -Method in class org.owasp.esapi.reference.FileBasedAccessController -
  -
assertAuthorizedForURL(String) - -Method in interface org.owasp.esapi.AccessController -
Checks if an account is authorized to access the referenced URL. -
assertAuthorizedForURL(String) - -Method in class org.owasp.esapi.reference.FileBasedAccessController -
  -
assertIsValidHTTPRequest() - -Method in interface org.owasp.esapi.Validator -
Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed - characters. -
assertIsValidHTTPRequest() - -Method in class org.owasp.esapi.reference.DefaultValidator -
Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed - characters. -
assertIsValidHTTPRequestParameterSet(String, Set, Set) - -Method in interface org.owasp.esapi.Validator -
Validates that the parameters in the current request contain all required parameters and only optional ones in - addition. -
assertIsValidHTTPRequestParameterSet(String, Set, Set, ValidationErrorList) - -Method in interface org.owasp.esapi.Validator -
Validates that the parameters in the current request contain all required parameters and only optional ones in - addition. -
assertIsValidHTTPRequestParameterSet(String, Set, Set) - -Method in class org.owasp.esapi.reference.DefaultValidator -
Validates that the parameters in the current request contain all required parameters and only optional ones in - addition. -
assertIsValidHTTPRequestParameterSet(String, Set, Set, ValidationErrorList) - -Method in class org.owasp.esapi.reference.DefaultValidator -
ValidationErrorList variant of assertIsValidHTTPRequestParameterSet -
assertSecureRequest(HttpServletRequest) - -Method in interface org.owasp.esapi.HTTPUtilities -
Ensures that the current request uses SSL and POST to protect any sensitive parameters - in the querystring from being sniffed or logged. -
assertSecureRequest(HttpServletRequest) - -Method in class org.owasp.esapi.reference.DefaultHTTPUtilities -
Verifies that the request is "secure" by checking that the method is a POST and - that SSL has been used. -
assertValidFileUpload(String, String, String, byte[], int, boolean) - -Method in interface org.owasp.esapi.Validator -
Validates the filepath, filename, and content of a file. -
assertValidFileUpload(String, String, String, byte[], int, boolean, ValidationErrorList) - -Method in interface org.owasp.esapi.Validator -
Validates the filepath, filename, and content of a file. -
assertValidFileUpload(String, String, String, byte[], int, boolean) - -Method in class org.owasp.esapi.reference.DefaultValidator -
Validates the filepath, filename, and content of a file. -
assertValidFileUpload(String, String, String, byte[], int, boolean, ValidationErrorList) - -Method in class org.owasp.esapi.reference.DefaultValidator -
ValidationErrorList variant of assertValidFileUpload -
authenticator() - -Static method in class org.owasp.esapi.ESAPI -
  -
-
- - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
- - - diff --git a/javadoc/index-files/index-10.html b/javadoc/index-files/index-10.html deleted file mode 100644 index 9cf2d4729..000000000 --- a/javadoc/index-files/index-10.html +++ /dev/null @@ -1,143 +0,0 @@ - - - - - - -J-Index - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
-

-J

-
-
JavaEncryptor - class org.owasp.esapi.reference.JavaEncryptor.
Reference implementation of the Encryptor interface.
JavaEncryptor() - -Constructor for class org.owasp.esapi.reference.JavaEncryptor -
  -
JavaLogFactory - class org.owasp.esapi.reference.JavaLogFactory.
Reference implementation of the LogFactory and Logger interfaces.
JavaLogFactory(String) - -Constructor for class org.owasp.esapi.reference.JavaLogFactory -
  -
JavaScriptCodec - class org.owasp.esapi.codecs.JavaScriptCodec.
Implementation of the Codec interface for backslash encoding frequently used in JavaScript.
JavaScriptCodec() - -Constructor for class org.owasp.esapi.codecs.JavaScriptCodec -
  -
-
- - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
- - - diff --git a/javadoc/index-files/index-11.html b/javadoc/index-files/index-11.html deleted file mode 100644 index d7fde2444..000000000 --- a/javadoc/index-files/index-11.html +++ /dev/null @@ -1,152 +0,0 @@ - - - - - - -K-Index - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
-

-K

-
-
keySet() - -Method in interface org.owasp.esapi.EncryptedProperties -
Key set. -
keySet() - -Method in class org.owasp.esapi.reference.DefaultEncryptedProperties -
Key set. -
killAllCookies(HttpServletRequest, HttpServletResponse) - -Method in interface org.owasp.esapi.HTTPUtilities -
Kill all cookies received in the last request from the browser. -
killAllCookies(HttpServletRequest, HttpServletResponse) - -Method in class org.owasp.esapi.reference.DefaultHTTPUtilities -
  -
killCookie(HttpServletRequest, HttpServletResponse, String) - -Method in interface org.owasp.esapi.HTTPUtilities -
Kills the specified cookie by setting a new cookie that expires immediately. -
killCookie(HttpServletRequest, HttpServletResponse, String) - -Method in class org.owasp.esapi.reference.DefaultHTTPUtilities -
  -
-
- - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
- - - diff --git a/javadoc/index-files/index-12.html b/javadoc/index-files/index-12.html deleted file mode 100644 index 2fcb7d8c2..000000000 --- a/javadoc/index-files/index-12.html +++ /dev/null @@ -1,195 +0,0 @@ - - - - - - -L-Index - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
-

-L

-
-
LogFactory - interface org.owasp.esapi.LogFactory.
The LogFactory interface is intended to allow substitution of various logging packages, while providing - a common interface to access them.
Logger - interface org.owasp.esapi.Logger.
The Logger interface defines a set of methods that can be used to log - security events.
LoggerTest - class org.owasp.esapi.reference.LoggerTest.
The Class LoggerTest.
LoggerTest(String) - -Constructor for class org.owasp.esapi.reference.LoggerTest -
Instantiates a new logger test. -
load(InputStream) - -Method in interface org.owasp.esapi.EncryptedProperties -
Load. -
load(InputStream) - -Method in class org.owasp.esapi.reference.DefaultEncryptedProperties -
Load. -
lock() - -Method in interface org.owasp.esapi.User -
Lock the user's account. -
lock() - -Method in class org.owasp.esapi.reference.DefaultUser -
  -
log() - -Static method in class org.owasp.esapi.ESAPI -
  -
logHTTPRequest(HttpServletRequest, Logger) - -Method in interface org.owasp.esapi.HTTPUtilities -
Format the Source IP address, URL, URL parameters, and all form - parameters into a string suitable for the log file. -
logHTTPRequest(HttpServletRequest, Logger, List) - -Method in interface org.owasp.esapi.HTTPUtilities -
Format the Source IP address, URL, URL parameters, and all form - parameters into a string suitable for the log file. -
logHTTPRequest(HttpServletRequest, Logger) - -Method in class org.owasp.esapi.reference.DefaultHTTPUtilities -
  -
logHTTPRequest(HttpServletRequest, Logger, List) - -Method in class org.owasp.esapi.reference.DefaultHTTPUtilities -
Formats an HTTP request into a log suitable string. -
login(HttpServletRequest, HttpServletResponse) - -Method in interface org.owasp.esapi.Authenticator -
Authenticates the user's credentials from the HttpServletRequest if - necessary, creates a session if necessary, and sets the user as the - current user. -
login(HttpServletRequest, HttpServletResponse) - -Method in class org.owasp.esapi.reference.FileBasedAuthenticator -
This method should be called for every HTTP request, to login the current user either from the session of HTTP - request. -
loginWithPassword(String) - -Method in interface org.owasp.esapi.User -
Login with password. -
loginWithPassword(String) - -Method in class org.owasp.esapi.reference.DefaultUser -
  -
logout() - -Method in interface org.owasp.esapi.Authenticator -
Logs out the current user. -
logout() - -Method in interface org.owasp.esapi.User -
Logout this user. -
logout() - -Method in class org.owasp.esapi.reference.DefaultUser -
  -
logout() - -Method in class org.owasp.esapi.reference.FileBasedAuthenticator -
Log out the current user. -
-
- - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
- - - diff --git a/javadoc/index-files/index-13.html b/javadoc/index-files/index-13.html deleted file mode 100644 index 5e69b7ed2..000000000 --- a/javadoc/index-files/index-13.html +++ /dev/null @@ -1,157 +0,0 @@ - - - - - - -M-Index - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
-

-M

-
-
MYSQL_MODE - -Static variable in class org.owasp.esapi.codecs.MySQLCodec -
  -
MySQLCodec - class org.owasp.esapi.codecs.MySQLCodec.
Implementation of the Codec interface for MySQL strings.
MySQLCodec(int) - -Constructor for class org.owasp.esapi.codecs.MySQLCodec -
  -
main(String[]) - -Static method in class org.owasp.esapi.codecs.Base64 -
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. -
main(String[]) - -Static method in class org.owasp.esapi.codecs.HTMLEntityCodec -
  -
main(String[]) - -Static method in class org.owasp.esapi.reference.DefaultEncryptedProperties -
The main method. -
main(String[]) - -Static method in class org.owasp.esapi.reference.FileBasedAuthenticator -
Fail safe main program to add or update an account in an emergency. -
mark() - -Method in class org.owasp.esapi.codecs.PushbackString -
  -
-
- - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
- - - diff --git a/javadoc/index-files/index-14.html b/javadoc/index-files/index-14.html deleted file mode 100644 index 900a8e111..000000000 --- a/javadoc/index-files/index-14.html +++ /dev/null @@ -1,154 +0,0 @@ - - - - - - -N-Index - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
-

-N

-
-
NO_OPTIONS - -Static variable in class org.owasp.esapi.codecs.Base64 -
No options specified. -
name - -Variable in class org.owasp.esapi.SecurityConfiguration.Threshold -
  -
next() - -Method in class org.owasp.esapi.codecs.PushbackString -
  -
nextHex() - -Method in class org.owasp.esapi.codecs.PushbackString -
  -
normalize(String) - -Method in interface org.owasp.esapi.Encoder -
Reduce all non-ascii characters to their ASCII form so that simpler - validation rules can be applied. -
normalize(String) - -Method in class org.owasp.esapi.reference.DefaultEncoder -
Normalizes special characters down to ASCII using the Normalizer built - into Java. -
-
- - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
- - - diff --git a/javadoc/index-files/index-15.html b/javadoc/index-files/index-15.html deleted file mode 100644 index db02c2657..000000000 --- a/javadoc/index-files/index-15.html +++ /dev/null @@ -1,144 +0,0 @@ - - - - - - -O-Index - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
-

-O

-
-
ORDERED - -Static variable in class org.owasp.esapi.codecs.Base64 -
Encode using the special "ordered" dialect of Base64 described here: - http://www.faqs.org/qa/rfcc-1940.html. -
OracleCodec - class org.owasp.esapi.codecs.OracleCodec.
Implementation of the Codec interface for Oracle strings.
OracleCodec() - -Constructor for class org.owasp.esapi.codecs.OracleCodec -
  -
org.owasp.esapi - package org.owasp.esapi
The ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications.
org.owasp.esapi.codecs - package org.owasp.esapi.codecs
 
org.owasp.esapi.errors - package org.owasp.esapi.errors
A set of exception classes designed to model the error conditions that -frequently arise in enterprise web applications and web services.
org.owasp.esapi.filters - package org.owasp.esapi.filters
 
org.owasp.esapi.http - package org.owasp.esapi.http
A few simple mock classes to help test the ESAPI reference -implementation.
org.owasp.esapi.reference - package org.owasp.esapi.reference
This package contains reference implementations of the ESAPI interfaces.
org.owasp.esapi.tags - package org.owasp.esapi.tags
 
-
- - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
- - - diff --git a/javadoc/index-files/index-16.html b/javadoc/index-files/index-16.html deleted file mode 100644 index 0a8c63c0a..000000000 --- a/javadoc/index-files/index-16.html +++ /dev/null @@ -1,156 +0,0 @@ - - - - - - -P-Index - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
-

-P

-
-
PERFORMANCE - -Static variable in interface org.owasp.esapi.Logger -
  -
PercentCodec - class org.owasp.esapi.codecs.PercentCodec.
Implementation of the Codec interface for percent encoding (aka URL encoding).
PercentCodec() - -Constructor for class org.owasp.esapi.codecs.PercentCodec -
  -
PushbackString - class org.owasp.esapi.codecs.PushbackString.
The pushback string is used by Codecs to allow them to push decoded characters back onto a string - for further decoding.
PushbackString(String) - -Constructor for class org.owasp.esapi.codecs.PushbackString -
  -
peek() - -Method in class org.owasp.esapi.codecs.PushbackString -
  -
peek(char) - -Method in class org.owasp.esapi.codecs.PushbackString -
  -
pushback(Character) - -Method in class org.owasp.esapi.codecs.PushbackString -
  -
putValue(String, Object) - -Method in class org.owasp.esapi.http.TestHttpSession -
  -
-
- - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
- - - diff --git a/javadoc/index-files/index-17.html b/javadoc/index-files/index-17.html deleted file mode 100644 index 114c7e9ba..000000000 --- a/javadoc/index-files/index-17.html +++ /dev/null @@ -1,226 +0,0 @@ - - - - - - -R-Index - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
-

-R

-
-
REMEMBER_TOKEN_COOKIE_NAME - -Static variable in interface org.owasp.esapi.HTTPUtilities -
Key for remember token cookie -
RESOURCE_DIRECTORY - -Static variable in class org.owasp.esapi.reference.DefaultSecurityConfiguration -
  -
RandomAccessReferenceMap - class org.owasp.esapi.reference.RandomAccessReferenceMap.
Reference implementation of the AccessReferenceMap interface.
RandomAccessReferenceMap() - -Constructor for class org.owasp.esapi.reference.RandomAccessReferenceMap -
This AccessReferenceMap implementation uses short random strings to - create a layer of indirection. -
RandomAccessReferenceMap(Set) - -Constructor for class org.owasp.esapi.reference.RandomAccessReferenceMap -
Instantiates a new access reference map. -
Randomizer - interface org.owasp.esapi.Randomizer.
The IRandomizer interface defines a set of methods for creating - cryptographically random numbers and strings.
RandomizerTest - class org.owasp.esapi.reference.RandomizerTest.
The Class RandomizerTest.
RandomizerTest(String) - -Constructor for class org.owasp.esapi.reference.RandomizerTest -
Instantiates a new randomizer test. -
randomizer() - -Static method in class org.owasp.esapi.ESAPI -
  -
read() - -Method in class org.owasp.esapi.codecs.Base64.InputStream -
Reads enough of the input stream to convert - to/from Base64 and returns the next byte. -
read(byte[], int, int) - -Method in class org.owasp.esapi.codecs.Base64.InputStream -
Calls Base64.InputStream.read() repeatedly until the end of stream - is reached or len bytes are read. -
read() - -Method in class org.owasp.esapi.http.TestServletInputStream -
read -
removeAttribute(String) - -Method in class org.owasp.esapi.filters.SafeRequest -
Same as HttpServletRequest, no security changes required. -
removeAttribute(String) - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
removeAttribute(String) - -Method in class org.owasp.esapi.http.TestHttpSession -
  -
removeDirectReference(Object) - -Method in interface org.owasp.esapi.AccessReferenceMap -
Removes a direct reference and its associated indirect reference from the AccessReferenceMap. -
removeDirectReference(Object) - -Method in class org.owasp.esapi.reference.IntegerAccessReferenceMap -
Remove a direct reference and the corresponding indirect reference. -
removeDirectReference(Object) - -Method in class org.owasp.esapi.reference.RandomAccessReferenceMap -
Remove a direct reference and the corresponding indirect reference. -
removeParameter(String) - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
removeRole(String) - -Method in interface org.owasp.esapi.User -
Removes a role from an account. -
removeRole(String) - -Method in class org.owasp.esapi.reference.DefaultUser -
  -
removeUser(String) - -Method in interface org.owasp.esapi.Authenticator -
Removes the account. -
removeUser(String) - -Method in class org.owasp.esapi.reference.FileBasedAuthenticator -
  -
removeValue(String) - -Method in class org.owasp.esapi.http.TestHttpSession -
  -
reset() - -Method in class org.owasp.esapi.codecs.PushbackString -
  -
reset() - -Method in class org.owasp.esapi.filters.SafeResponse -
Same as HttpServletResponse, no security changes required. -
reset() - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
resetBuffer() - -Method in class org.owasp.esapi.filters.SafeResponse -
Same as HttpServletResponse, no security changes required. -
resetBuffer() - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
resetCSRFToken() - -Method in interface org.owasp.esapi.User -
Returns a token to be used as a prevention against CSRF attacks. -
resetCSRFToken() - -Method in class org.owasp.esapi.reference.DefaultUser -
In this implementation, we have chosen to use a random token that is - stored in the User object. -
resumeEncoding() - -Method in class org.owasp.esapi.codecs.Base64.OutputStream -
Resumes encoding of the stream. -
-
- - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
- - - diff --git a/javadoc/index-files/index-18.html b/javadoc/index-files/index-18.html deleted file mode 100644 index 4e1d8b540..000000000 --- a/javadoc/index-files/index-18.html +++ /dev/null @@ -1,544 +0,0 @@ - - - - - - -S-Index - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
-

-S

-
-
SECURITY - -Static variable in interface org.owasp.esapi.Logger -
  -
SafeFile - class org.owasp.esapi.SafeFile.
Extension to java.io.File to prevent against null byte injections and - other unforeseen problems resulting from unprintable characters - causing problems in path lookups.
SafeFile(String) - -Constructor for class org.owasp.esapi.SafeFile -
  -
SafeFile(String, String) - -Constructor for class org.owasp.esapi.SafeFile -
  -
SafeFile(File, String) - -Constructor for class org.owasp.esapi.SafeFile -
  -
SafeFile(URI) - -Constructor for class org.owasp.esapi.SafeFile -
  -
SafeFileTest - class org.owasp.esapi.reference.SafeFileTest.
The Class ExecutorTest.
SafeFileTest(String) - -Constructor for class org.owasp.esapi.reference.SafeFileTest -
Instantiates a new executor test. -
SafeHTTPFilter - class org.owasp.esapi.filters.SafeHTTPFilter.
This filter wraps the incoming request and outgoing response and overrides - many methods with safer versions.
SafeHTTPFilter() - -Constructor for class org.owasp.esapi.filters.SafeHTTPFilter -
  -
SafeRequest - class org.owasp.esapi.filters.SafeRequest.
This request wrapper simply overrides unsafe methods in the HttpServletRequest - API with safe versions that return canonicalized data where possible.
SafeRequest(HttpServletRequest) - -Constructor for class org.owasp.esapi.filters.SafeRequest -
Construct a safe request that overrides the default request methods with safer versions. -
SafeResponse - class org.owasp.esapi.filters.SafeResponse.
This response wrapper simply overrides unsafe methods in the - HttpServletResponse API with safe versions.
SafeResponse(HttpServletResponse) - -Constructor for class org.owasp.esapi.filters.SafeResponse -
Construct a safe response that overrides the default response methods - with safer versions. -
SecurityConfiguration - interface org.owasp.esapi.SecurityConfiguration.
The ISecurityConfiguration interface stores all configuration information - that directs the behavior of the ESAPI implementation.
SecurityConfiguration.Threshold - class org.owasp.esapi.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.
SecurityConfiguration.Threshold(String, int, long, List) - -Constructor for class org.owasp.esapi.SecurityConfiguration.Threshold -
  -
StringUtilities - class org.owasp.esapi.StringUtilities.
String utilities used in various filters.
StringUtilities() - -Constructor for class org.owasp.esapi.StringUtilities -
  -
safeReadLine(InputStream, int) - -Method in interface org.owasp.esapi.Validator -
Reads from an input stream until end-of-line or a maximum number of - characters. -
safeReadLine(InputStream, int) - -Method in class org.owasp.esapi.reference.DefaultValidator -
This implementation reads until a newline or the specified number of - characters. -
safeSendForward(HttpServletRequest, HttpServletResponse, String, String) - -Method in interface org.owasp.esapi.HTTPUtilities -
This method perform a forward to any resource located inside the WEB-INF directory. -
safeSendForward(HttpServletRequest, HttpServletResponse, String, String) - -Method in class org.owasp.esapi.reference.DefaultHTTPUtilities -
  -
safeSetContentType(HttpServletResponse) - -Method in interface org.owasp.esapi.HTTPUtilities -
Sets the content type on each HTTP response, to help protect against cross-site scripting attacks and other types - of injection into HTML documents. -
safeSetContentType(HttpServletResponse) - -Method in class org.owasp.esapi.reference.DefaultHTTPUtilities -
Set the character encoding on every HttpServletResponse in order to limit - the ways in which the input data can be represented. -
seal(String, long) - -Method in interface org.owasp.esapi.Encryptor -
Creates a seal that binds a set of data and includes an expiration timestamp. -
seal(String, long) - -Method in class org.owasp.esapi.reference.JavaEncryptor -
  -
securityConfiguration() - -Static method in class org.owasp.esapi.ESAPI -
  -
sendError(int) - -Method in class org.owasp.esapi.filters.SafeResponse -
Override the error code with a 200 in order to confound attackers using - automated scanners. -
sendError(int, String) - -Method in class org.owasp.esapi.filters.SafeResponse -
Override the error code with a 200 in order to confound attackers using - automated scanners. -
sendError(int) - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
sendError(int, String) - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
sendRedirect(String) - -Method in class org.owasp.esapi.filters.SafeResponse -
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. -
sendRedirect(String) - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
setAccessController(AccessController) - -Static method in class org.owasp.esapi.ESAPI -
  -
setAccessedTime(long) - -Method in class org.owasp.esapi.http.TestHttpSession -
  -
setAccountName(String) - -Method in interface org.owasp.esapi.User -
Sets the account name. -
setAccountName(String) - -Method in class org.owasp.esapi.reference.DefaultUser -
Sets the account name. -
setAttribute(String, Object) - -Method in class org.owasp.esapi.filters.SafeRequest -
Same as HttpServletRequest, no security changes required. -
setAttribute(String, Object) - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
setAttribute(String, Object) - -Method in class org.owasp.esapi.http.TestHttpSession -
  -
setAuthenticator(Authenticator) - -Static method in class org.owasp.esapi.ESAPI -
  -
setBufferSize(int) - -Method in class org.owasp.esapi.filters.SafeResponse -
Same as HttpServletResponse, no security changes required. -
setBufferSize(int) - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
setCharacterEncoding(String) - -Method in class org.owasp.esapi.filters.SafeRequest -
Sets the character encoding to the ESAPI configured encoding. -
setCharacterEncoding(String) - -Method in class org.owasp.esapi.filters.SafeResponse -
Sets the character encoding to the ESAPI configured encoding. -
setCharacterEncoding(String) - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
setCharacterEncoding(String) - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
setContentLength(int) - -Method in class org.owasp.esapi.filters.SafeResponse -
Same as HttpServletResponse, no security changes required. -
setContentLength(int) - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
setContentType(String) - -Method in class org.owasp.esapi.filters.SafeResponse -
Same as HttpServletResponse, no security changes required. -
setContentType(String) - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
setContentType(String) - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
setContext(String) - -Method in class org.owasp.esapi.errors.ValidationException -
Set's the UI reference that caused this ValidationException -
setCookie(String, String) - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
setCookies(ArrayList) - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
Sets the cookies. -
setCreationTime(long) - -Method in class org.owasp.esapi.http.TestHttpSession -
  -
setCurrentHTTP(HttpServletRequest, HttpServletResponse) - -Method in interface org.owasp.esapi.HTTPUtilities -
Stores the current HttpRequest and HttpResponse so that they may be readily accessed throughout - ESAPI (and elsewhere) -
setCurrentHTTP(HttpServletRequest, HttpServletResponse) - -Method in class org.owasp.esapi.reference.DefaultHTTPUtilities -
  -
setCurrentUser(User) - -Method in interface org.owasp.esapi.Authenticator -
Sets the currently logged in User. -
setCurrentUser(User) - -Method in class org.owasp.esapi.reference.FileBasedAuthenticator -
  -
setDateHeader(String, long) - -Method in class org.owasp.esapi.filters.SafeResponse -
Add a date header to the response after ensuring that there are no - encoded or illegal characters in the name. -
setDateHeader(String, long) - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
setEncoder(Encoder) - -Static method in class org.owasp.esapi.ESAPI -
  -
setEncryptor(Encryptor) - -Static method in class org.owasp.esapi.ESAPI -
  -
setExecutor(Executor) - -Static method in class org.owasp.esapi.ESAPI -
  -
setExpirationTime(Date) - -Method in interface org.owasp.esapi.User -
Sets the time when this user's account will expire. -
setExpirationTime(Date) - -Method in class org.owasp.esapi.reference.DefaultUser -
Sets the expiration time. -
setHeader(String, String) - -Method in class org.owasp.esapi.filters.SafeResponse -
Add a header to the response after ensuring that there are no encoded or - illegal characters in the name and value. -
setHeader(String, String) - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
setHttpUtilities(HTTPUtilities) - -Static method in class org.owasp.esapi.ESAPI -
  -
setIntHeader(String, int) - -Method in class org.owasp.esapi.filters.SafeResponse -
Add an int header to the response after ensuring that there are no - encoded or illegal characters in the name. -
setIntHeader(String, int) - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
setIntrusionDetector(IntrusionDetector) - -Static method in class org.owasp.esapi.ESAPI -
  -
setLastFailedLoginTime(Date) - -Method in interface org.owasp.esapi.User -
Set the time of the last failed login for this user. -
setLastFailedLoginTime(Date) - -Method in class org.owasp.esapi.reference.DefaultUser -
Sets the last failed login time. -
setLastHostAddress(String) - -Method in interface org.owasp.esapi.User -
Set the last remote host address used by this user. -
setLastHostAddress(String) - -Method in class org.owasp.esapi.reference.DefaultUser -
Sets the last remote host address used by this User. -
setLastLoginTime(Date) - -Method in interface org.owasp.esapi.User -
Set the time of the last successful login for this user. -
setLastLoginTime(Date) - -Method in class org.owasp.esapi.reference.DefaultUser -
Sets the last login time. -
setLastPasswordChangeTime(Date) - -Method in interface org.owasp.esapi.User -
Set the time of the last password change for this user. -
setLastPasswordChangeTime(Date) - -Method in class org.owasp.esapi.reference.DefaultUser -
Sets the last password change time. -
setLocale(Locale) - -Method in class org.owasp.esapi.filters.SafeResponse -
Same as HttpServletResponse, no security changes required. -
setLocale(Locale) - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
setLogFactory(LogFactory) - -Static method in class org.owasp.esapi.ESAPI -
  -
setMaxInactiveInterval(int) - -Method in class org.owasp.esapi.http.TestHttpSession -
  -
setMethod(String) - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
setName(String) - -Method in class org.owasp.esapi.tags.EncodeForHTMLAttributeTag -
  -
setName(String) - -Method in class org.owasp.esapi.tags.EncodeForHTMLJavaScriptTag -
  -
setName(String) - -Method in class org.owasp.esapi.tags.EncodeForHTMLTag -
  -
setName(String) - -Method in class org.owasp.esapi.tags.EncodeForVBScriptTag -
  -
setNoCacheHeaders(HttpServletResponse) - -Method in interface org.owasp.esapi.HTTPUtilities -
Set headers to protect sensitive information against being cached in the browser. -
setNoCacheHeaders(HttpServletResponse) - -Method in class org.owasp.esapi.reference.DefaultHTTPUtilities -
Set headers to protect sensitive information against being cached in the - browser. -
setProperty(String, String) - -Method in interface org.owasp.esapi.EncryptedProperties -
Encrypts the plaintext property value and stores the ciphertext value in the encrypted store. -
setProperty(String, String) - -Method in class org.owasp.esapi.reference.DefaultEncryptedProperties -
  -
setRandomizer(Randomizer) - -Static method in class org.owasp.esapi.ESAPI -
  -
setRememberToken(HttpServletRequest, HttpServletResponse, String, int, String, String) - -Method in interface org.owasp.esapi.HTTPUtilities -
Set a cookie containing the current User's remember me token for automatic authentication. -
setRememberToken(HttpServletRequest, HttpServletResponse, String, int, String, String) - -Method in class org.owasp.esapi.reference.DefaultHTTPUtilities -
Save the user's remember me token in a cookie. -
setRequestURI(String) - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
setResourceDirectory(String) - -Method in interface org.owasp.esapi.SecurityConfiguration -
Sets the ESAPI resource directory. -
setResourceDirectory(String) - -Method in class org.owasp.esapi.reference.DefaultSecurityConfiguration -
  -
setRoles(Set) - -Method in interface org.owasp.esapi.User -
Sets the roles of this account. -
setRoles(Set) - -Method in class org.owasp.esapi.reference.DefaultUser -
Sets the roles. -
setScreenName(String) - -Method in interface org.owasp.esapi.User -
Sets the screen name. -
setScreenName(String) - -Method in class org.owasp.esapi.reference.DefaultUser -
  -
setSecurityConfiguration(SecurityConfiguration) - -Static method in class org.owasp.esapi.ESAPI -
  -
setStatus(int) - -Method in class org.owasp.esapi.filters.SafeResponse -
Override the status code with a 200 in order to confound attackers using - automated scanners. -
setStatus(int, String) - -Method in class org.owasp.esapi.filters.SafeResponse -
Override the status code with a 200 in order to confound attackers using - automated scanners. -
setStatus(int) - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
setStatus(int, String) - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
setValidator(Validator) - -Static method in class org.owasp.esapi.ESAPI -
  -
sign(String) - -Method in interface org.owasp.esapi.Encryptor -
Create a digital signature for the provided data and return it in a - string. -
sign(String) - -Method in class org.owasp.esapi.reference.JavaEncryptor -
  -
size() - -Method in class org.owasp.esapi.ValidationErrorList -
Returns the numbers of errors present. -
store(OutputStream, String) - -Method in interface org.owasp.esapi.EncryptedProperties -
Store. -
store(OutputStream, String) - -Method in class org.owasp.esapi.reference.DefaultEncryptedProperties -
Store. -
stripControls(String) - -Static method in class org.owasp.esapi.StringUtilities -
Removes all unprintable characters from a string - and replaces with a space for use in an HTTP header -
suite() - -Static method in class org.owasp.esapi.AllTests -
suite method automatically generated by JUnit module. -
suite() - -Static method in class org.owasp.esapi.ESAPITest -
Suite. -
suite() - -Static method in class org.owasp.esapi.errors.EnterpriseSecurityExceptionTest -
Suite. -
suite() - -Static method in class org.owasp.esapi.filters.ESAPIFilterTest -
Suite. -
suite() - -Static method in class org.owasp.esapi.reference.AccessControllerTest -
Suite. -
suite() - -Static method in class org.owasp.esapi.reference.AccessReferenceMapTest -
Suite. -
suite() - -Static method in class org.owasp.esapi.reference.AuthenticatorTest -
Suite. -
suite() - -Static method in class org.owasp.esapi.reference.EncoderTest -
Suite. -
suite() - -Static method in class org.owasp.esapi.reference.EncryptedPropertiesTest -
Suite. -
suite() - -Static method in class org.owasp.esapi.reference.EncryptorTest -
Suite. -
suite() - -Static method in class org.owasp.esapi.reference.ExecutorTest -
Suite. -
suite() - -Static method in class org.owasp.esapi.reference.HTTPUtilitiesTest -
Suite. -
suite() - -Static method in class org.owasp.esapi.reference.IntegerAccessReferenceMapTest -
Suite. -
suite() - -Static method in class org.owasp.esapi.reference.IntrusionDetectorTest -
Suite. -
suite() - -Static method in class org.owasp.esapi.reference.LoggerTest -
Suite. -
suite() - -Static method in class org.owasp.esapi.reference.RandomizerTest -
Suite. -
suite() - -Static method in class org.owasp.esapi.reference.SafeFileTest -
Suite. -
suite() - -Static method in class org.owasp.esapi.reference.UserTest -
Suite. -
suite() - -Static method in class org.owasp.esapi.reference.ValidatorTest -
Suite. -
suspendEncoding() - -Method in class org.owasp.esapi.codecs.Base64.OutputStream -
Suspends encoding of the stream. -
-
- - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
- - - diff --git a/javadoc/index-files/index-19.html b/javadoc/index-files/index-19.html deleted file mode 100644 index f7c5fdb17..000000000 --- a/javadoc/index-files/index-19.html +++ /dev/null @@ -1,618 +0,0 @@ - - - - - - -T-Index - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
-

-T

-
-
TestFilterChain - class org.owasp.esapi.http.TestFilterChain.
 
TestFilterChain() - -Constructor for class org.owasp.esapi.http.TestFilterChain -
  -
TestHttpServletRequest - class org.owasp.esapi.http.TestHttpServletRequest.
The Class TestHttpServletRequest.
TestHttpServletRequest() - -Constructor for class org.owasp.esapi.http.TestHttpServletRequest -
  -
TestHttpServletRequest(String, byte[]) - -Constructor for class org.owasp.esapi.http.TestHttpServletRequest -
  -
TestHttpServletResponse - class org.owasp.esapi.http.TestHttpServletResponse.
The Class TestHttpServletResponse.
TestHttpServletResponse() - -Constructor for class org.owasp.esapi.http.TestHttpServletResponse -
  -
TestHttpSession - class org.owasp.esapi.http.TestHttpSession.
The Class TestHttpSession.
TestHttpSession() - -Constructor for class org.owasp.esapi.http.TestHttpSession -
Instantiates a new test http session. -
TestHttpSession(long, long) - -Constructor for class org.owasp.esapi.http.TestHttpSession -
Instantiates a new test http session. -
TestRequestDispatcher - class org.owasp.esapi.http.TestRequestDispatcher.
 
TestRequestDispatcher() - -Constructor for class org.owasp.esapi.http.TestRequestDispatcher -
  -
TestServletInputStream - class org.owasp.esapi.http.TestServletInputStream.
 
TestServletInputStream(byte[]) - -Constructor for class org.owasp.esapi.http.TestServletInputStream -
constructor -
testAddCSRFToken() - -Method in class org.owasp.esapi.reference.HTTPUtilitiesTest -
Test of addCSRFToken method, of class org.owasp.esapi.HTTPUtilities. -
testAddDirectReference() - -Method in class org.owasp.esapi.reference.AccessReferenceMapTest -
  -
testAddDirectReference() - -Method in class org.owasp.esapi.reference.IntegerAccessReferenceMapTest -
  -
testAddEvent() - -Method in class org.owasp.esapi.reference.IntrusionDetectorTest -
Test of addEvent method, of class org.owasp.esapi.IntrusionDetector. -
testAddException() - -Method in class org.owasp.esapi.reference.IntrusionDetectorTest -
Test of addException method, of class org.owasp.esapi.IntrusionDetector. -
testAddRole() - -Method in class org.owasp.esapi.reference.UserTest -
Test of testAddRole method, of class org.owasp.esapi.User. -
testAddRoles() - -Method in class org.owasp.esapi.reference.UserTest -
Test of addRoles method, of class org.owasp.esapi.User. -
testAlternateDataStream() - -Method in class org.owasp.esapi.reference.SafeFileTest -
  -
testCanonicalize() - -Method in class org.owasp.esapi.reference.EncoderTest -
Test of canonicalize method, of class org.owasp.esapi.Encoder. -
testChangePassword() - -Method in class org.owasp.esapi.reference.UserTest -
Test of changePassword method, of class org.owasp.esapi.User. -
testChangeSessionIdentifier() - -Method in class org.owasp.esapi.reference.HTTPUtilitiesTest -
Test of sendRedirect method, of class org.owasp.esapi.HTTPUtilities. -
testCreateSafeFile() - -Method in class org.owasp.esapi.reference.SafeFileTest -
Test of executeOSCommand method, of class org.owasp.esapi.Executor -
testCreateSafeFileParentConstructor() - -Method in class org.owasp.esapi.reference.SafeFileTest -
  -
testCreateSafeFileURIConstructor() - -Method in class org.owasp.esapi.reference.SafeFileTest -
  -
testCreateUser() - -Method in class org.owasp.esapi.reference.AuthenticatorTest -
Test of createAccount method, of class org.owasp.esapi.Authenticator. -
testDebug() - -Method in class org.owasp.esapi.reference.LoggerTest -
Test of logDebug method, of class org.owasp.esapi.Logger. -
testDecodeFromBase64() - -Method in class org.owasp.esapi.reference.EncoderTest -
Test of decodeFromBase64 method, of class org.owasp.esapi.Encoder. -
testDecodeFromURL() - -Method in class org.owasp.esapi.reference.EncoderTest -
Test of decodeFromURL method, of class org.owasp.esapi.Encoder. -
testDecrypt() - -Method in class org.owasp.esapi.reference.EncryptorTest -
Test of decrypt method, of class org.owasp.esapi.Encryptor. -
testDisable() - -Method in class org.owasp.esapi.reference.UserTest -
Test of disable method, of class org.owasp.esapi.User. -
testEnable() - -Method in class org.owasp.esapi.reference.UserTest -
Test of enable method, of class org.owasp.esapi.User. -
testEncodeForBase64() - -Method in class org.owasp.esapi.reference.EncoderTest -
Test of encodeForBase64 method, of class org.owasp.esapi.Encoder. -
testEncodeForCSS() - -Method in class org.owasp.esapi.reference.EncoderTest -
  -
testEncodeForDN() - -Method in class org.owasp.esapi.reference.EncoderTest -
Test of encodeForLDAP method, of class org.owasp.esapi.Encoder. -
testEncodeForHTML() - -Method in class org.owasp.esapi.reference.EncoderTest -
Test of encodeForHTML method, of class org.owasp.esapi.Encoder. -
testEncodeForHTMLAttribute() - -Method in class org.owasp.esapi.reference.EncoderTest -
Test of encodeForHTMLAttribute method, of class org.owasp.esapi.Encoder. -
testEncodeForJavascript() - -Method in class org.owasp.esapi.reference.EncoderTest -
Test of encodeForJavaScript method, of class org.owasp.esapi.Encoder. -
testEncodeForLDAP() - -Method in class org.owasp.esapi.reference.EncoderTest -
Test of encodeForLDAP method, of class org.owasp.esapi.Encoder. -
testEncodeForSQL() - -Method in class org.owasp.esapi.reference.EncoderTest -
Test of encodeForSQL method, of class org.owasp.esapi.Encoder. -
testEncodeForURL() - -Method in class org.owasp.esapi.reference.EncoderTest -
Test of encodeForURL method, of class org.owasp.esapi.Encoder. -
testEncodeForVBScript() - -Method in class org.owasp.esapi.reference.EncoderTest -
  -
testEncodeForXML() - -Method in class org.owasp.esapi.reference.EncoderTest -
Test of encodeForXML method, of class org.owasp.esapi.Encoder. -
testEncodeForXMLAttribute() - -Method in class org.owasp.esapi.reference.EncoderTest -
Test of encodeForXMLAttribute method, of class org.owasp.esapi.Encoder. -
testEncodeForXPath() - -Method in class org.owasp.esapi.reference.EncoderTest -
Test of encodeForXPath method, of class org.owasp.esapi.Encoder. -
testEncrypt() - -Method in class org.owasp.esapi.reference.EncryptorTest -
Test of encrypt method, of class org.owasp.esapi.Encryptor. -
testError() - -Method in class org.owasp.esapi.reference.LoggerTest -
Test of logError method, of class org.owasp.esapi.Logger. -
testExceptions() - -Method in class org.owasp.esapi.errors.EnterpriseSecurityExceptionTest -
Test of update method, of class org.owasp.esapi.AccessReferenceMap. -
testExecuteSystemCommand() - -Method in class org.owasp.esapi.reference.ExecutorTest -
Test of executeOSCommand method, of class org.owasp.esapi.Executor -
testExists() - -Method in class org.owasp.esapi.reference.AuthenticatorTest -
Test of exists method, of class org.owasp.esapi.Authenticator. -
testFailedLoginLockout() - -Method in class org.owasp.esapi.reference.UserTest -
Test of failedLoginCount lockout, of class org.owasp.esapi.User. -
testFatal() - -Method in class org.owasp.esapi.reference.LoggerTest -
Test of logCritical method, of class org.owasp.esapi.Logger. -
testFilter() - -Method in class org.owasp.esapi.filters.ESAPIFilterTest -
Test of update method, of class org.owasp.esapi.AccessReferenceMap. -
testGenerateStrongPassword() - -Method in class org.owasp.esapi.reference.AuthenticatorTest -
Test of generateStrongPassword method, of class - org.owasp.esapi.Authenticator. -
testGetAccountName() - -Method in class org.owasp.esapi.reference.UserTest -
Test of getAccountName method, of class org.owasp.esapi.User. -
testGetCurrentUser() - -Method in class org.owasp.esapi.reference.AuthenticatorTest -
Test of getCurrentUser method, of class org.owasp.esapi.Authenticator. -
testGetDirectReference() - -Method in class org.owasp.esapi.reference.AccessReferenceMapTest -
Test of getDirectReference method, of class - org.owasp.esapi.AccessReferenceMap. -
testGetDirectReference() - -Method in class org.owasp.esapi.reference.IntegerAccessReferenceMapTest -
Test of getDirectReference method, of class - org.owasp.esapi.AccessReferenceMap. -
testGetFileUploads() - -Method in class org.owasp.esapi.reference.HTTPUtilitiesTest -
Test of formatHttpRequestForLog method, of class org.owasp.esapi.HTTPUtilities. -
testGetIndirectReference() - -Method in class org.owasp.esapi.reference.AccessReferenceMapTest -
Test of getIndirectReference method, of class - org.owasp.esapi.AccessReferenceMap. -
testGetIndirectReference() - -Method in class org.owasp.esapi.reference.IntegerAccessReferenceMapTest -
Test of getIndirectReference method, of class - org.owasp.esapi.AccessReferenceMap. -
testGetLastFailedLoginTime() - -Method in class org.owasp.esapi.reference.UserTest -
Test get last failed login time. -
testGetLastLoginTime() - -Method in class org.owasp.esapi.reference.UserTest -
Test get last login time. -
testGetLastPasswordChangeTime() - -Method in class org.owasp.esapi.reference.UserTest -
Test of getLastPasswordChangeTime method, of class org.owasp.esapi.User. -
testGetProperty() - -Method in class org.owasp.esapi.reference.EncryptedPropertiesTest -
Test of getProperty method, of class org.owasp.esapi.EncryptedProperties. -
testGetRandomGUID() - -Method in class org.owasp.esapi.reference.RandomizerTest -
Test of getRandomGUID method, of class org.owasp.esapi.Randomizer. -
testGetRandomInteger() - -Method in class org.owasp.esapi.reference.RandomizerTest -
Test of getRandomInteger method, of class org.owasp.esapi.Randomizer. -
testGetRandomReal() - -Method in class org.owasp.esapi.reference.RandomizerTest -
Test of getRandomReal method, of class org.owasp.esapi.Randomizer. -
testGetRandomString() - -Method in class org.owasp.esapi.reference.RandomizerTest -
Test of getRandomString method, of class org.owasp.esapi.Randomizer. -
testGetRoles() - -Method in class org.owasp.esapi.reference.UserTest -
Test of getRoles method, of class org.owasp.esapi.User. -
testGetScreenName() - -Method in class org.owasp.esapi.reference.UserTest -
Test of xxx method, of class org.owasp.esapi.User. -
testGetStateFromEncryptedCookie() - -Method in class org.owasp.esapi.reference.HTTPUtilitiesTest -
  -
testGetUser() - -Method in class org.owasp.esapi.reference.AuthenticatorTest -
Test of getUser method, of class org.owasp.esapi.Authenticator. -
testGetUserFromRememberToken() - -Method in class org.owasp.esapi.reference.AuthenticatorTest -
  -
testGetUserFromSession() - -Method in class org.owasp.esapi.reference.AuthenticatorTest -
Test get user from session. -
testGetUserNames() - -Method in class org.owasp.esapi.reference.AuthenticatorTest -
Test get user names. -
testGetValidDate() - -Method in class org.owasp.esapi.reference.ValidatorTest -
Test of getValidDate method, of class org.owasp.esapi.Validator. -
testGetValidSafeHTML() - -Method in class org.owasp.esapi.reference.ValidatorTest -
Test of getValidSafeHTML method, of class org.owasp.esapi.Validator. -
testHash() - -Method in class org.owasp.esapi.reference.EncryptorTest -
Test of hash method, of class org.owasp.esapi.Encryptor. -
testHashPassword() - -Method in class org.owasp.esapi.reference.AuthenticatorTest -
Test of hashPassword method, of class org.owasp.esapi.Authenticator. -
testIncrementFailedLoginCount() - -Method in class org.owasp.esapi.reference.UserTest -
Test of incrementFailedLoginCount method, of class org.owasp.esapi.User. -
testInfo() - -Method in class org.owasp.esapi.reference.LoggerTest -
Test of logSuccess method, of class org.owasp.esapi.Logger. -
testIsAuthorizedForBackendService() - -Method in class org.owasp.esapi.reference.AccessControllerTest -
Test of isAuthorizedForBackendService method, of class - org.owasp.esapi.AccessController. -
testIsAuthorizedForData() - -Method in class org.owasp.esapi.reference.AccessControllerTest -
Test of isAuthorizedForData method, of class - org.owasp.esapi.AccessController. -
testIsAuthorizedForFile() - -Method in class org.owasp.esapi.reference.AccessControllerTest -
Test of isAuthorizedForFile method, of class - org.owasp.esapi.AccessController. -
testIsAuthorizedForFunction() - -Method in class org.owasp.esapi.reference.AccessControllerTest -
Test of isAuthorizedForFunction method, of class - org.owasp.esapi.AccessController. -
testIsAuthorizedForURL() - -Method in class org.owasp.esapi.reference.AccessControllerTest -
Test of isAuthorizedForURL method, of class - org.owasp.esapi.AccessController. -
testIsEnabled() - -Method in class org.owasp.esapi.reference.UserTest -
Test of isEnabled method, of class org.owasp.esapi.User. -
testIsInRole() - -Method in class org.owasp.esapi.reference.UserTest -
Test of isInRole method, of class org.owasp.esapi.User. -
testIsLocked() - -Method in class org.owasp.esapi.reference.UserTest -
Test of xxx method, of class org.owasp.esapi.User. -
testIsSessionAbsoluteTimeout() - -Method in class org.owasp.esapi.reference.UserTest -
Test of isSessionAbsoluteTimeout method, of class - org.owasp.esapi.IntrusionDetector. -
testIsSessionTimeout() - -Method in class org.owasp.esapi.reference.UserTest -
Test of isSessionTimeout method, of class - org.owasp.esapi.IntrusionDetector. -
testIsValidCreditCard() - -Method in class org.owasp.esapi.reference.ValidatorTest -
Test of isValidCreditCard method, of class org.owasp.esapi.Validator. -
testIsValidDirectoryPath() - -Method in class org.owasp.esapi.reference.ValidatorTest -
Test of isValidDirectoryPath method, of class org.owasp.esapi.Validator. -
testIsValidFileContent() - -Method in class org.owasp.esapi.reference.ValidatorTest -
Test of isValidFileContent method, of class org.owasp.esapi.Validator. -
testIsValidFileName() - -Method in class org.owasp.esapi.reference.ValidatorTest -
Test of isValidFileName method, of class org.owasp.esapi.Validator. -
testIsValidFileUpload() - -Method in class org.owasp.esapi.reference.ValidatorTest -
Test of isValidFileUpload method, of class org.owasp.esapi.Validator. -
testIsValidHTTPRequest() - -Method in class org.owasp.esapi.reference.HTTPUtilitiesTest -
Test of isValidHTTPRequest method, of class org.owasp.esapi.HTTPUtilities. -
testIsValidInteger() - -Method in class org.owasp.esapi.reference.ValidatorTest -
  -
testIsValidListItem() - -Method in class org.owasp.esapi.reference.ValidatorTest -
Test of isValidListItem method, of class org.owasp.esapi.Validator. -
testIsValidNumber() - -Method in class org.owasp.esapi.reference.ValidatorTest -
Test of isValidNumber method, of class org.owasp.esapi.Validator. -
testIsValidParameterSet() - -Method in class org.owasp.esapi.reference.ValidatorTest -
Test of isValidParameterSet method, of class org.owasp.esapi.Validator. -
testIsValidPrintable() - -Method in class org.owasp.esapi.reference.ValidatorTest -
  -
testIsValidSafeHTML() - -Method in class org.owasp.esapi.reference.ValidatorTest -
Test of isValidSafeHTML method, of class org.owasp.esapi.Validator. -
testIterator() - -Method in class org.owasp.esapi.reference.AccessReferenceMapTest -
Test of iterator method, of class org.owasp.esapi.AccessReferenceMap. -
testIterator() - -Method in class org.owasp.esapi.reference.IntegerAccessReferenceMapTest -
Test of iterator method, of class org.owasp.esapi.AccessReferenceMap. -
testJavaDirInjection() - -Method in class org.owasp.esapi.reference.SafeFileTest -
  -
testJavaFileInjection() - -Method in class org.owasp.esapi.reference.SafeFileTest -
  -
testKeySet() - -Method in class org.owasp.esapi.reference.EncryptedPropertiesTest -
Test of keySet method, of class org.owasp.esapi.EncryptedProperties. -
testKillAllCookies() - -Method in class org.owasp.esapi.reference.HTTPUtilitiesTest -
Test of killAllCookies method, of class org.owasp.esapi.HTTPUtilities. -
testKillCookie() - -Method in class org.owasp.esapi.reference.HTTPUtilitiesTest -
Test of killCookie method, of class org.owasp.esapi.HTTPUtilities. -
testLoad() - -Method in class org.owasp.esapi.reference.EncryptedPropertiesTest -
Test of load method, of class org.owasp.esapi.EncryptedProperties. -
testLock() - -Method in class org.owasp.esapi.reference.UserTest -
Test of lockAccount method, of class org.owasp.esapi.User. -
testLogHTTPRequest() - -Method in class org.owasp.esapi.reference.LoggerTest -
Test of logHTTPRequest method, of class org.owasp.esapi.Logger. -
testLogin() - -Method in class org.owasp.esapi.reference.AuthenticatorTest -
Test of login method, of class org.owasp.esapi.Authenticator. -
testLoginWithPassword() - -Method in class org.owasp.esapi.reference.UserTest -
Test of loginWithPassword method, of class org.owasp.esapi.User. -
testLogout() - -Method in class org.owasp.esapi.reference.UserTest -
Test of logout method, of class org.owasp.esapi.User. -
testMain() - -Method in class org.owasp.esapi.reference.AuthenticatorTest -
Test of main method, of class org.owasp.esapi.Authenticator. -
testMain() - -Method in class org.owasp.esapi.reference.EncryptedPropertiesTest -
Test of store method, of class org.owasp.esapi.EncryptedProperties. -
testMatchRule() - -Method in class org.owasp.esapi.reference.AccessControllerTest -
  -
testMultipleJavaFileInjection() - -Method in class org.owasp.esapi.reference.SafeFileTest -
  -
testNormalPercentEncodedFileInjection() - -Method in class org.owasp.esapi.reference.SafeFileTest -
  -
testNormalize() - -Method in class org.owasp.esapi.reference.EncoderTest -
Test of normalize method, of class org.owasp.esapi.Validator. -
testRemoveDirectReference() - -Method in class org.owasp.esapi.reference.AccessReferenceMapTest -
  -
testRemoveDirectReference() - -Method in class org.owasp.esapi.reference.IntegerAccessReferenceMapTest -
  -
testRemoveRole() - -Method in class org.owasp.esapi.reference.UserTest -
Test of testRemoveRole method, of class org.owasp.esapi.User. -
testRemoveUser() - -Method in class org.owasp.esapi.reference.AuthenticatorTest -
Test of removeAccount method, of class org.owasp.esapi.Authenticator. -
testResetCSRFToken() - -Method in class org.owasp.esapi.reference.UserTest -
Test of testResetCSRFToken method, of class org.owasp.esapi.User. -
testSafeReadLine() - -Method in class org.owasp.esapi.reference.ValidatorTest -
Test safe read line. -
testSaveStateInEncryptedCookie() - -Method in class org.owasp.esapi.reference.HTTPUtilitiesTest -
  -
testSaveUsers() - -Method in class org.owasp.esapi.reference.AuthenticatorTest -
Test of saveUsers method, of class org.owasp.esapi.Authenticator. -
testSeal() - -Method in class org.owasp.esapi.reference.EncryptorTest -
Test of seal method, of class org.owasp.esapi.Encryptor. -
testSendSafeRedirect() - -Method in class org.owasp.esapi.reference.HTTPUtilitiesTest -
Test of sendRedirect method, of class org.owasp.esapi.HTTPUtilities. -
testSetAccountName() - -Method in class org.owasp.esapi.reference.UserTest -
Test of setAccountName method, of class org.owasp.esapi.User. -
testSetCookie() - -Method in class org.owasp.esapi.reference.HTTPUtilitiesTest -
Test of setCookie method, of class org.owasp.esapi.HTTPUtilities. -
testSetCurrentUser() - -Method in class org.owasp.esapi.reference.AuthenticatorTest -
Test of setCurrentUser method, of class org.owasp.esapi.Authenticator. -
testSetCurrentUserWithRequest() - -Method in class org.owasp.esapi.reference.AuthenticatorTest -
Test of setCurrentUser method, of class org.owasp.esapi.Authenticator. -
testSetExpirationTime() - -Method in class org.owasp.esapi.reference.UserTest -
Test of setExpirationTime method, of class org.owasp.esapi.User. -
testSetNoCacheHeaders() - -Method in class org.owasp.esapi.reference.HTTPUtilitiesTest -
Test set no cache headers. -
testSetProperty() - -Method in class org.owasp.esapi.reference.EncryptedPropertiesTest -
Test of setProperty method, of class org.owasp.esapi.EncryptedProperties. -
testSetRememberToken() - -Method in class org.owasp.esapi.reference.HTTPUtilitiesTest -
  -
testSetRoles() - -Method in class org.owasp.esapi.reference.UserTest -
Test of setRoles method, of class org.owasp.esapi.User. -
testSetScreenName() - -Method in class org.owasp.esapi.reference.UserTest -
Test of setScreenName method, of class org.owasp.esapi.User. -
testSetters() - -Method in class org.owasp.esapi.ESAPITest -
Test of all the ESAPI setter methods -
testSign() - -Method in class org.owasp.esapi.reference.EncryptorTest -
Test of sign method, of class org.owasp.esapi.Encryptor. -
testStore() - -Method in class org.owasp.esapi.reference.EncryptedPropertiesTest -
Test of store method, of class org.owasp.esapi.EncryptedProperties. -
testTrace() - -Method in class org.owasp.esapi.reference.LoggerTest -
Test of logTrace method, of class org.owasp.esapi.Logger. -
testUnlock() - -Method in class org.owasp.esapi.reference.UserTest -
Test of unlockAccount method, of class org.owasp.esapi.User. -
testUpdate() - -Method in class org.owasp.esapi.reference.AccessReferenceMapTest -
Test of update method, of class org.owasp.esapi.AccessReferenceMap. -
testUpdate() - -Method in class org.owasp.esapi.reference.IntegerAccessReferenceMapTest -
Test of update method, of class org.owasp.esapi.AccessReferenceMap. -
testValidatePasswordStrength() - -Method in class org.owasp.esapi.reference.AuthenticatorTest -
Test of validatePasswordStrength method, of class - org.owasp.esapi.Authenticator. -
testVerifySeal() - -Method in class org.owasp.esapi.reference.EncryptorTest -
Test of verifySeal method, of class org.owasp.esapi.Encryptor. -
testVerifySignature() - -Method in class org.owasp.esapi.reference.EncryptorTest -
Test of verifySignature method, of class org.owasp.esapi.Encryptor. -
testWarning() - -Method in class org.owasp.esapi.reference.LoggerTest -
Test of logWarning method, of class org.owasp.esapi.Logger. -
testWeirdPercentEncodedFileInjection() - -Method in class org.owasp.esapi.reference.SafeFileTest -
  -
testisValidInput() - -Method in class org.owasp.esapi.reference.ValidatorTest -
Test of isValidEmailAddress method, of class org.owasp.esapi.Validator. -
toHex(byte) - -Static method in class org.owasp.esapi.reference.SafeFileTest -
  -
toString() - -Method in class org.owasp.esapi.reference.DefaultUser -
  -
trace(String, String) - -Method in interface org.owasp.esapi.Logger -
Log trace. -
trace(String, String, Throwable) - -Method in interface org.owasp.esapi.Logger -
Log trace. -
-
- - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
- - - diff --git a/javadoc/index-files/index-2.html b/javadoc/index-files/index-2.html deleted file mode 100644 index d067834a1..000000000 --- a/javadoc/index-files/index-2.html +++ /dev/null @@ -1,152 +0,0 @@ - - - - - - -B-Index - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
-

-B

-
-
Base64 - class org.owasp.esapi.codecs.Base64.
Encodes and decodes to and from Base64 notation.
Base64.InputStream - class org.owasp.esapi.codecs.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.
Base64.InputStream(InputStream) - -Constructor for class org.owasp.esapi.codecs.Base64.InputStream -
Constructs a Base64.InputStream in DECODE mode. -
Base64.InputStream(InputStream, int) - -Constructor for class org.owasp.esapi.codecs.Base64.InputStream -
Constructs a Base64.InputStream in - either ENCODE or DECODE mode. -
Base64.OutputStream - class org.owasp.esapi.codecs.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.
Base64.OutputStream(OutputStream) - -Constructor for class org.owasp.esapi.codecs.Base64.OutputStream -
Constructs a Base64.OutputStream in ENCODE mode. -
Base64.OutputStream(OutputStream, int) - -Constructor for class org.owasp.esapi.codecs.Base64.OutputStream -
Constructs a Base64.OutputStream in - either ENCODE or DECODE mode. -
-
- - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
- - - diff --git a/javadoc/index-files/index-20.html b/javadoc/index-files/index-20.html deleted file mode 100644 index 4728f00e8..000000000 --- a/javadoc/index-files/index-20.html +++ /dev/null @@ -1,174 +0,0 @@ - - - - - - -U-Index - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
-

-U

-
-
URL_SAFE - -Static variable in class org.owasp.esapi.codecs.Base64 -
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. -
USABILITY - -Static variable in interface org.owasp.esapi.Logger -
  -
User - interface org.owasp.esapi.User.
The User interface represents an application user or user account.
UserTest - class org.owasp.esapi.reference.UserTest.
The Class UserTest.
UserTest(String) - -Constructor for class org.owasp.esapi.reference.UserTest -
Instantiates a new user test. -
union(char[], char[]) - -Static method in class org.owasp.esapi.StringUtilities -
Union two character arrays. -
unlock() - -Method in interface org.owasp.esapi.User -
Unlock account. -
unlock() - -Method in class org.owasp.esapi.reference.DefaultUser -
  -
unseal(String) - -Method in interface org.owasp.esapi.Encryptor -
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. -
unseal(String) - -Method in class org.owasp.esapi.reference.JavaEncryptor -
  -
update(Set) - -Method in interface org.owasp.esapi.AccessReferenceMap -
Updates the access reference map with a new set of directReferences, maintaining - any existing indirectReferences associated with items that are in the new list. -
update(Set) - -Method in class org.owasp.esapi.reference.IntegerAccessReferenceMap -
This preserves any existing mappings for items that are still in the new - list. -
update(Set) - -Method in class org.owasp.esapi.reference.RandomAccessReferenceMap -
This preserves any existing mappings for items that are still in the new - list. -
-
- - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
- - - diff --git a/javadoc/index-files/index-21.html b/javadoc/index-files/index-21.html deleted file mode 100644 index 5fb27686d..000000000 --- a/javadoc/index-files/index-21.html +++ /dev/null @@ -1,221 +0,0 @@ - - - - - - -V-Index - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
-

-V

-
-
VBScriptCodec - class org.owasp.esapi.codecs.VBScriptCodec.
Implementation of the Codec interface for 'quote' encoding from VBScript.
VBScriptCodec() - -Constructor for class org.owasp.esapi.codecs.VBScriptCodec -
  -
ValidationAvailabilityException - exception org.owasp.esapi.errors.ValidationAvailabilityException.
 
ValidationAvailabilityException(String, String) - -Constructor for class org.owasp.esapi.errors.ValidationAvailabilityException -
Create a new ValidationException -
ValidationAvailabilityException(String, String, Throwable) - -Constructor for class org.owasp.esapi.errors.ValidationAvailabilityException -
Create a new ValidationException -
ValidationErrorList - class org.owasp.esapi.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.
ValidationErrorList() - -Constructor for class org.owasp.esapi.ValidationErrorList -
  -
ValidationException - exception org.owasp.esapi.errors.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.
ValidationException(String, String) - -Constructor for class org.owasp.esapi.errors.ValidationException -
Creates a new instance of ValidationException. -
ValidationException(String, String, Throwable) - -Constructor for class org.owasp.esapi.errors.ValidationException -
Instantiates a new ValidationException. -
ValidationException(String, String, String) - -Constructor for class org.owasp.esapi.errors.ValidationException -
Creates a new instance of ValidationException. -
ValidationException(String, String, Throwable, String) - -Constructor for class org.owasp.esapi.errors.ValidationException -
Instantiates a new ValidationException. -
ValidationUploadException - exception org.owasp.esapi.errors.ValidationUploadException.
 
ValidationUploadException(String, String) - -Constructor for class org.owasp.esapi.errors.ValidationUploadException -
Create a new ValidationException -
ValidationUploadException(String, String, Throwable) - -Constructor for class org.owasp.esapi.errors.ValidationUploadException -
Create a new ValidationException -
Validator - interface org.owasp.esapi.Validator.
The Validator interface defines a set of methods for canonicalizing and - validating untrusted input.
ValidatorTest - class org.owasp.esapi.reference.ValidatorTest.
The Class ValidatorTest.
ValidatorTest(String) - -Constructor for class org.owasp.esapi.reference.ValidatorTest -
Instantiates a new validator test. -
validator() - -Static method in class org.owasp.esapi.ESAPI -
  -
verifyAccountNameStrength(String) - -Method in interface org.owasp.esapi.Authenticator -
Ensures that the account name passes site-specific complexity requirements, like minimum length. -
verifyAccountNameStrength(String) - -Method in class org.owasp.esapi.reference.FileBasedAuthenticator -
  -
verifyCSRFToken(HttpServletRequest) - -Method in interface org.owasp.esapi.HTTPUtilities -
Checks the CSRF token in the URL (see User.getCSRFToken()) against the user's CSRF token and - throws an IntrusionException if it is missing. -
verifyCSRFToken(HttpServletRequest) - -Method in class org.owasp.esapi.reference.DefaultHTTPUtilities -
  -
verifyPassword(User, String) - -Method in interface org.owasp.esapi.Authenticator -
Verify that the supplied password matches the password for this user. -
verifyPassword(String) - -Method in interface org.owasp.esapi.User -
Verify that the supplied password matches the password for this user. -
verifyPassword(String) - -Method in class org.owasp.esapi.reference.DefaultUser -
  -
verifyPassword(User, String) - -Method in class org.owasp.esapi.reference.FileBasedAuthenticator -
  -
verifyPasswordStrength(String, String) - -Method in interface org.owasp.esapi.Authenticator -
Ensures that the password meets site-specific complexity requirements. -
verifyPasswordStrength(String, String) - -Method in class org.owasp.esapi.reference.FileBasedAuthenticator -
  -
verifySeal(String) - -Method in interface org.owasp.esapi.Encryptor -
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. -
verifySeal(String) - -Method in class org.owasp.esapi.reference.JavaEncryptor -
  -
verifySignature(String, String) - -Method in interface org.owasp.esapi.Encryptor -
Verifies a digital signature (created with the sign method) and returns - the boolean result. -
verifySignature(String, String) - -Method in class org.owasp.esapi.reference.JavaEncryptor -
  -
-
- - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
- - - diff --git a/javadoc/index-files/index-22.html b/javadoc/index-files/index-22.html deleted file mode 100644 index d18f17048..000000000 --- a/javadoc/index-files/index-22.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - -W-Index - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
-

-W

-
-
warning(String, String) - -Method in interface org.owasp.esapi.Logger -
Log warning. -
warning(String, String, Throwable) - -Method in interface org.owasp.esapi.Logger -
Log warning. -
write(int) - -Method in class org.owasp.esapi.codecs.Base64.OutputStream -
Writes the byte to the output stream after - converting to/from Base64 notation. -
write(byte[], int, int) - -Method in class org.owasp.esapi.codecs.Base64.OutputStream -
Calls Base64.OutputStream.write(int) repeatedly until len - bytes are written. -
-
- - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
- - - diff --git a/javadoc/index-files/index-3.html b/javadoc/index-files/index-3.html deleted file mode 100644 index 99f9f3034..000000000 --- a/javadoc/index-files/index-3.html +++ /dev/null @@ -1,252 +0,0 @@ - - - - - - -C-Index - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
-

-C

-
-
CHAR_ALPHANUMERICS - -Static variable in interface org.owasp.esapi.Encoder -
  -
CHAR_DIGITS - -Static variable in interface org.owasp.esapi.Encoder -
  -
CHAR_LETTERS - -Static variable in interface org.owasp.esapi.Encoder -
  -
CHAR_LOWERS - -Static variable in interface org.owasp.esapi.Encoder -
Standard character sets -
CHAR_PASSWORD_DIGITS - -Static variable in interface org.owasp.esapi.Encoder -
  -
CHAR_PASSWORD_LETTERS - -Static variable in interface org.owasp.esapi.Encoder -
  -
CHAR_PASSWORD_LOWERS - -Static variable in interface org.owasp.esapi.Encoder -
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_SPECIALS - -Static variable in interface org.owasp.esapi.Encoder -
  -
CHAR_PASSWORD_UPPERS - -Static variable in interface org.owasp.esapi.Encoder -
  -
CHAR_SPECIALS - -Static variable in interface org.owasp.esapi.Encoder -
  -
CHAR_UPPERS - -Static variable in interface org.owasp.esapi.Encoder -
  -
CSSCodec - class org.owasp.esapi.codecs.CSSCodec.
Implementation of the Codec interface for backslash encoding frequently used in JavaScript.
CSSCodec() - -Constructor for class org.owasp.esapi.codecs.CSSCodec -
  -
CertificateException - exception org.owasp.esapi.errors.CertificateException.
A CertificateException should be thrown for any problems that arise during - processing of digital certificates.
CertificateException(String, String) - -Constructor for class org.owasp.esapi.errors.CertificateException -
Creates a new instance of CertificateException. -
CertificateException(String, String, Throwable) - -Constructor for class org.owasp.esapi.errors.CertificateException -
Instantiates a new CertificateException. -
Codec - interface org.owasp.esapi.codecs.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).
canonicalize(String) - -Method in interface org.owasp.esapi.Encoder -
This method performs canonicalization on data received to ensure that it - has been reduced to its most basic form before validation. -
canonicalize(String, boolean) - -Method in interface org.owasp.esapi.Encoder -
  -
canonicalize(String) - -Method in class org.owasp.esapi.reference.DefaultEncoder -
Simplifies encoded characters to their - simplest form so that they can be properly validated. -
canonicalize(String, boolean) - -Method in class org.owasp.esapi.reference.DefaultEncoder -
Strict mode throws an exception when any double encoded data is detected. -
changePassword(User, String, String, String) - -Method in interface org.owasp.esapi.Authenticator -
Changes the password for the specified user. -
changePassword(String, String, String) - -Method in interface org.owasp.esapi.User -
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. -
changePassword(String, String, String) - -Method in class org.owasp.esapi.reference.DefaultUser -
  -
changePassword(User, String, String, String) - -Method in class org.owasp.esapi.reference.FileBasedAuthenticator -
  -
changeSessionIdentifier(HttpServletRequest) - -Method in interface org.owasp.esapi.HTTPUtilities -
Invalidate the old session after copying all of its contents to a newly created session with a new session id. -
changeSessionIdentifier(HttpServletRequest) - -Method in class org.owasp.esapi.reference.DefaultHTTPUtilities -
  -
clearCookies() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
clearCurrent() - -Method in interface org.owasp.esapi.Authenticator -
Clear the current user. -
clearCurrent() - -Method in class org.owasp.esapi.reference.FileBasedAuthenticator -
Clears all threadlocal variables from the thread. -
clone() - -Method in class org.owasp.esapi.reference.DefaultUser -
Override clone and make final to prevent duplicate user objects. -
close() - -Method in class org.owasp.esapi.codecs.Base64.OutputStream -
Flushes and closes (I think, in the superclass) the stream. -
contains(StringBuffer, char) - -Static method in class org.owasp.esapi.StringUtilities -
Returns true if the character is contained in the provided StringBuffer. -
containsHeader(String) - -Method in class org.owasp.esapi.filters.SafeResponse -
Same as HttpServletResponse, no security changes required. -
containsHeader(String) - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
count - -Variable in class org.owasp.esapi.SecurityConfiguration.Threshold -
  -
createUser(String, String, String) - -Method in interface org.owasp.esapi.Authenticator -
Creates a new User with the information provided. -
createUser(String, String, String) - -Method in class org.owasp.esapi.reference.FileBasedAuthenticator -
  -
currentRequest() - -Static method in class org.owasp.esapi.ESAPI -
  -
currentResponse() - -Static method in class org.owasp.esapi.ESAPI -
  -
-
- - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
- - - diff --git a/javadoc/index-files/index-4.html b/javadoc/index-files/index-4.html deleted file mode 100644 index d5b29cbf1..000000000 --- a/javadoc/index-files/index-4.html +++ /dev/null @@ -1,340 +0,0 @@ - - - - - - -D-Index - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
-

-D

-
-
DECODE - -Static variable in class org.owasp.esapi.codecs.Base64 -
Specify decoding. -
DONT_BREAK_LINES - -Static variable in class org.owasp.esapi.codecs.Base64 -
Don't break lines when encoding (violates strict Base64 specification) -
DefaultEncoder - class org.owasp.esapi.reference.DefaultEncoder.
Reference implementation of the Encoder interface.
DefaultEncoder() - -Constructor for class org.owasp.esapi.reference.DefaultEncoder -
  -
DefaultEncryptedProperties - class org.owasp.esapi.reference.DefaultEncryptedProperties.
Reference implementation of the EncryptedProperties interface.
DefaultEncryptedProperties() - -Constructor for class org.owasp.esapi.reference.DefaultEncryptedProperties -
Instantiates a new encrypted properties. -
DefaultExecutor - class org.owasp.esapi.reference.DefaultExecutor.
Reference implementation of the Executor interface.
DefaultExecutor() - -Constructor for class org.owasp.esapi.reference.DefaultExecutor -
  -
DefaultHTTPUtilities - class org.owasp.esapi.reference.DefaultHTTPUtilities.
Reference implementation of the HTTPUtilities interface.
DefaultHTTPUtilities() - -Constructor for class org.owasp.esapi.reference.DefaultHTTPUtilities -
  -
DefaultIntrusionDetector - class org.owasp.esapi.reference.DefaultIntrusionDetector.
Reference implementation of the IntrusionDetector interface.
DefaultIntrusionDetector() - -Constructor for class org.owasp.esapi.reference.DefaultIntrusionDetector -
  -
DefaultRandomizer - class org.owasp.esapi.reference.DefaultRandomizer.
Reference implementation of the Randomizer interface.
DefaultRandomizer() - -Constructor for class org.owasp.esapi.reference.DefaultRandomizer -
Hide the constructor for the Singleton pattern. -
DefaultSecurityConfiguration - class org.owasp.esapi.reference.DefaultSecurityConfiguration.
The SecurityConfiguration manages all the settings used by the ESAPI in a single place.
DefaultSecurityConfiguration() - -Constructor for class org.owasp.esapi.reference.DefaultSecurityConfiguration -
Instantiates a new configuration. -
DefaultUser - class org.owasp.esapi.reference.DefaultUser.
Reference implementation of the User interface.
DefaultValidator - class org.owasp.esapi.reference.DefaultValidator.
Reference implementation of the Validator interface.
DefaultValidator() - -Constructor for class org.owasp.esapi.reference.DefaultValidator -
  -
debug(String, String) - -Method in interface org.owasp.esapi.Logger -
Log debug. -
debug(String, String, Throwable) - -Method in interface org.owasp.esapi.Logger -
Log debug. -
decode(byte[], int, int, int) - -Static method in class org.owasp.esapi.codecs.Base64 -
Very low-level access to decoding ASCII characters in - the form of a byte array. -
decode(String) - -Static method in class org.owasp.esapi.codecs.Base64 -
Decodes data from Base64 notation, automatically - detecting gzip-compressed data and decompressing it. -
decode(String, int) - -Static method in class org.owasp.esapi.codecs.Base64 -
Decodes data from Base64 notation, automatically - detecting gzip-compressed data and decompressing it. -
decode(String) - -Method in class org.owasp.esapi.codecs.CSSCodec -
  -
decode(String) - -Method in interface org.owasp.esapi.codecs.Codec -
  -
decode(String) - -Method in class org.owasp.esapi.codecs.HTMLEntityCodec -
  -
decode(String) - -Method in class org.owasp.esapi.codecs.JavaScriptCodec -
  -
decode(String) - -Method in class org.owasp.esapi.codecs.MySQLCodec -
  -
decode(String) - -Method in class org.owasp.esapi.codecs.OracleCodec -
  -
decode(String) - -Method in class org.owasp.esapi.codecs.PercentCodec -
  -
decode(String) - -Method in class org.owasp.esapi.codecs.VBScriptCodec -
  -
decodeCharacter(PushbackString) - -Method in class org.owasp.esapi.codecs.CSSCodec -
Returns the decoded version of the character starting at index, or - null if no decoding is possible. -
decodeCharacter(PushbackString) - -Method in interface org.owasp.esapi.codecs.Codec -
Returns the decoded version of the next character from the input string and advances the - current character in the PushbackString. -
decodeCharacter(PushbackString) - -Method in class org.owasp.esapi.codecs.HTMLEntityCodec -
Returns the decoded version of the character starting at index, or - null if no decoding is possible. -
decodeCharacter(PushbackString) - -Method in class org.owasp.esapi.codecs.JavaScriptCodec -
Returns the decoded version of the character starting at index, or - null if no decoding is possible. -
decodeCharacter(PushbackString) - -Method in class org.owasp.esapi.codecs.MySQLCodec -
Returns the decoded version of the character starting at index, or - null if no decoding is possible. -
decodeCharacter(PushbackString) - -Method in class org.owasp.esapi.codecs.OracleCodec -
Returns the decoded version of the character starting at index, or - null if no decoding is possible. -
decodeCharacter(PushbackString) - -Method in class org.owasp.esapi.codecs.PercentCodec -
Returns the decoded version of the character starting at index, or - null if no decoding is possible. -
decodeCharacter(PushbackString) - -Method in class org.owasp.esapi.codecs.VBScriptCodec -
Returns the decoded version of the character starting at index, or - null if no decoding is possible. -
decodeFileToFile(String, String) - -Static method in class org.owasp.esapi.codecs.Base64 -
Reads infile and decodes it to outfile. -
decodeFromBase64(String) - -Method in interface org.owasp.esapi.Encoder -
Decode data encoded with BASE-64 encoding. -
decodeFromBase64(String) - -Method in class org.owasp.esapi.reference.DefaultEncoder -
  -
decodeFromFile(String) - -Static method in class org.owasp.esapi.codecs.Base64 -
Convenience method for reading a base64-encoded - file and decoding it. -
decodeFromURL(String) - -Method in interface org.owasp.esapi.Encoder -
Decode from URL. -
decodeFromURL(String) - -Method in class org.owasp.esapi.reference.DefaultEncoder -
  -
decodeToFile(String, String) - -Static method in class org.owasp.esapi.codecs.Base64 -
Convenience method for decoding data to a file. -
decodeToObject(String) - -Static method in class org.owasp.esapi.codecs.Base64 -
Attempts to decode Base64 data and deserialize a Java - Object within. -
decrypt(String) - -Method in interface org.owasp.esapi.Encryptor -
Decrypts the provided ciphertext string (encrypted with the encrypt - method) and returns a plaintext string. -
decrypt(String) - -Method in class org.owasp.esapi.reference.JavaEncryptor -
  -
decryptHiddenField(String) - -Method in interface org.owasp.esapi.HTTPUtilities -
Decrypts an encrypted hidden field value and returns the cleartext. -
decryptHiddenField(String) - -Method in class org.owasp.esapi.reference.DefaultHTTPUtilities -
  -
decryptQueryString(String) - -Method in interface org.owasp.esapi.HTTPUtilities -
Takes an encrypted querystring and returns a Map containing the original parameters. -
decryptQueryString(String) - -Method in class org.owasp.esapi.reference.DefaultHTTPUtilities -
  -
decryptStateFromCookie(HttpServletRequest) - -Method in interface org.owasp.esapi.HTTPUtilities -
Retrieves a map of data from a cookie encrypted with encryptStateInCookie(). -
decryptStateFromCookie(HttpServletRequest) - -Method in class org.owasp.esapi.reference.DefaultHTTPUtilities -
  -
destroy() - -Method in class org.owasp.esapi.filters.ESAPIFilter -
Called by the web container to indicate to a filter that it is being - taken out of service. -
destroy() - -Method in class org.owasp.esapi.filters.SafeHTTPFilter -
  -
disable() - -Method in interface org.owasp.esapi.User -
Disable account. -
disable() - -Method in class org.owasp.esapi.reference.DefaultUser -
  -
doAfterBody() - -Method in class org.owasp.esapi.tags.EncodeForHTMLAttributeTag -
  -
doAfterBody() - -Method in class org.owasp.esapi.tags.EncodeForHTMLJavaScriptTag -
  -
doAfterBody() - -Method in class org.owasp.esapi.tags.EncodeForHTMLTag -
  -
doAfterBody() - -Method in class org.owasp.esapi.tags.EncodeForVBScriptTag -
  -
doEndTag() - -Method in class org.owasp.esapi.tags.EncodeForVBScriptTag -
  -
doFilter(ServletRequest, ServletResponse, FilterChain) - -Method in class org.owasp.esapi.filters.ESAPIFilter -
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. -
doFilter(ServletRequest, ServletResponse, FilterChain) - -Method in class org.owasp.esapi.filters.SafeHTTPFilter -
  -
doFilter(ServletRequest, ServletResponse) - -Method in class org.owasp.esapi.http.TestFilterChain -
  -
doStartTag() - -Method in class org.owasp.esapi.tags.EncodeForHTMLAttributeTag -
  -
doStartTag() - -Method in class org.owasp.esapi.tags.EncodeForHTMLJavaScriptTag -
  -
doStartTag() - -Method in class org.owasp.esapi.tags.EncodeForHTMLTag -
  -
doStartTag() - -Method in class org.owasp.esapi.tags.EncodeForVBScriptTag -
  -
-
- - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
- - - diff --git a/javadoc/index-files/index-5.html b/javadoc/index-files/index-5.html deleted file mode 100644 index 41d97bd65..000000000 --- a/javadoc/index-files/index-5.html +++ /dev/null @@ -1,453 +0,0 @@ - - - - - - -E-Index - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
-

-E

-
-
ENCODE - -Static variable in class org.owasp.esapi.codecs.Base64 -
Specify encoding. -
ESAPI - class org.owasp.esapi.ESAPI.
ESAPI locator class to make it easy to get a concrete implementation of the - various ESAPI classes.
ESAPIFilter - class org.owasp.esapi.filters.ESAPIFilter.
 
ESAPIFilter() - -Constructor for class org.owasp.esapi.filters.ESAPIFilter -
  -
ESAPIFilterTest - class org.owasp.esapi.filters.ESAPIFilterTest.
The Class AccessReferenceMapTest.
ESAPIFilterTest(String) - -Constructor for class org.owasp.esapi.filters.ESAPIFilterTest -
Instantiates a new access reference map test. -
ESAPITest - class org.owasp.esapi.ESAPITest.
The Class ExecutorTest.
ESAPITest(String) - -Constructor for class org.owasp.esapi.ESAPITest -
Instantiates a new executor test. -
EncodeForHTMLAttributeTag - class org.owasp.esapi.tags.EncodeForHTMLAttributeTag.
 
EncodeForHTMLAttributeTag() - -Constructor for class org.owasp.esapi.tags.EncodeForHTMLAttributeTag -
  -
EncodeForHTMLJavaScriptTag - class org.owasp.esapi.tags.EncodeForHTMLJavaScriptTag.
 
EncodeForHTMLJavaScriptTag() - -Constructor for class org.owasp.esapi.tags.EncodeForHTMLJavaScriptTag -
  -
EncodeForHTMLTag - class org.owasp.esapi.tags.EncodeForHTMLTag.
 
EncodeForHTMLTag() - -Constructor for class org.owasp.esapi.tags.EncodeForHTMLTag -
  -
EncodeForVBScriptTag - class org.owasp.esapi.tags.EncodeForVBScriptTag.
 
EncodeForVBScriptTag() - -Constructor for class org.owasp.esapi.tags.EncodeForVBScriptTag -
  -
Encoder - interface org.owasp.esapi.Encoder.
The Encoder interface contains a number of methods related to encoding input - so that it will be safe for a variety of interpreters.
EncoderTest - class org.owasp.esapi.reference.EncoderTest.
The Class EncoderTest.
EncoderTest(String) - -Constructor for class org.owasp.esapi.reference.EncoderTest -
Instantiates a new encoder test. -
EncodingException - exception org.owasp.esapi.errors.EncodingException.
An ExecutorException should be thrown for any problems that occur when - encoding or decoding data.
EncodingException(String, String) - -Constructor for class org.owasp.esapi.errors.EncodingException -
Creates a new instance of EncodingException. -
EncodingException(String, String, Throwable) - -Constructor for class org.owasp.esapi.errors.EncodingException -
Instantiates a new EncodingException. -
EncryptedProperties - interface org.owasp.esapi.EncryptedProperties.
The EncryptedProperties interface represents a properties file where all the data is - encrypted before it is added, and decrypted when it retrieved.
EncryptedPropertiesTest - class org.owasp.esapi.reference.EncryptedPropertiesTest.
The Class EncryptedPropertiesTest.
EncryptedPropertiesTest(String) - -Constructor for class org.owasp.esapi.reference.EncryptedPropertiesTest -
Instantiates a new encrypted properties test. -
EncryptionException - exception org.owasp.esapi.errors.EncryptionException.
An EncryptionException should be thrown for any problems related to - encryption, hashing, or digital signatures.
EncryptionException(String, String) - -Constructor for class org.owasp.esapi.errors.EncryptionException -
Creates a new instance of EncryptionException. -
EncryptionException(String, String, Throwable) - -Constructor for class org.owasp.esapi.errors.EncryptionException -
Instantiates a new EncryptionException. -
Encryptor - interface org.owasp.esapi.Encryptor.
The Encryptor interface provides a set of methods for performing common - encryption, random number, and hashing operations.
EncryptorTest - class org.owasp.esapi.reference.EncryptorTest.
The Class EncryptorTest.
EncryptorTest(String) - -Constructor for class org.owasp.esapi.reference.EncryptorTest -
Instantiates a new encryptor test. -
EnterpriseSecurityException - exception org.owasp.esapi.errors.EnterpriseSecurityException.
EnterpriseSecurityException is the base class for all security related exceptions.
EnterpriseSecurityException(String, String) - -Constructor for class org.owasp.esapi.errors.EnterpriseSecurityException -
Creates a new instance of EnterpriseSecurityException. -
EnterpriseSecurityException(String, String, Throwable) - -Constructor for class org.owasp.esapi.errors.EnterpriseSecurityException -
Creates a new instance of EnterpriseSecurityException that includes a root cause Throwable. -
EnterpriseSecurityExceptionTest - class org.owasp.esapi.errors.EnterpriseSecurityExceptionTest.
The Class AccessReferenceMapTest.
EnterpriseSecurityExceptionTest(String) - -Constructor for class org.owasp.esapi.errors.EnterpriseSecurityExceptionTest -
Instantiates a new access reference map test. -
Executor - interface org.owasp.esapi.Executor.
The Executor interface is used to run an OS command with reduced security risk.
ExecutorException - exception org.owasp.esapi.errors.ExecutorException.
An ExecutorException should be thrown for any problems that arise during the - execution of a system executable.
ExecutorException(String, String) - -Constructor for class org.owasp.esapi.errors.ExecutorException -
Creates a new instance of ExecutorException. -
ExecutorException(String, String, Throwable) - -Constructor for class org.owasp.esapi.errors.ExecutorException -
Instantiates a new ExecutorException. -
ExecutorTest - class org.owasp.esapi.reference.ExecutorTest.
The Class ExecutorTest.
ExecutorTest(String) - -Constructor for class org.owasp.esapi.reference.ExecutorTest -
Instantiates a new executor test. -
enable() - -Method in interface org.owasp.esapi.User -
Enable account. -
enable() - -Method in class org.owasp.esapi.reference.DefaultUser -
Enable the account -
encode(String) - -Method in class org.owasp.esapi.codecs.CSSCodec -
  -
encode(String) - -Method in interface org.owasp.esapi.codecs.Codec -
  -
encode(String) - -Method in class org.owasp.esapi.codecs.HTMLEntityCodec -
  -
encode(String) - -Method in class org.owasp.esapi.codecs.JavaScriptCodec -
  -
encode(String) - -Method in class org.owasp.esapi.codecs.MySQLCodec -
  -
encode(String) - -Method in class org.owasp.esapi.codecs.OracleCodec -
  -
encode(String) - -Method in class org.owasp.esapi.codecs.PercentCodec -
  -
encode(String) - -Method in class org.owasp.esapi.codecs.VBScriptCodec -
  -
encodeBytes(byte[]) - -Static method in class org.owasp.esapi.codecs.Base64 -
Encodes a byte array into Base64 notation. -
encodeBytes(byte[], int) - -Static method in class org.owasp.esapi.codecs.Base64 -
Encodes a byte array into Base64 notation. -
encodeBytes(byte[], int, int) - -Static method in class org.owasp.esapi.codecs.Base64 -
Encodes a byte array into Base64 notation. -
encodeBytes(byte[], int, int, int) - -Static method in class org.owasp.esapi.codecs.Base64 -
Encodes a byte array into Base64 notation. -
encodeCharacter(Character) - -Method in class org.owasp.esapi.codecs.CSSCodec -
Returns backslash encoded character. -
encodeCharacter(Character) - -Method in interface org.owasp.esapi.codecs.Codec -
  -
encodeCharacter(Character) - -Method in class org.owasp.esapi.codecs.HTMLEntityCodec -
  -
encodeCharacter(Character) - -Method in class org.owasp.esapi.codecs.JavaScriptCodec -
Returns backslash encoded character. -
encodeCharacter(Character) - -Method in class org.owasp.esapi.codecs.MySQLCodec -
Returns quote-encoded character -
encodeCharacter(Character) - -Method in class org.owasp.esapi.codecs.OracleCodec -
Returns quote-encoded character -
encodeCharacter(Character) - -Method in class org.owasp.esapi.codecs.PercentCodec -
  -
encodeCharacter(Character) - -Method in class org.owasp.esapi.codecs.VBScriptCodec -
Returns quote-encoded character -
encodeFileToFile(String, String) - -Static method in class org.owasp.esapi.codecs.Base64 -
Reads infile and encodes it to outfile. -
encodeForBase64(byte[], boolean) - -Method in interface org.owasp.esapi.Encoder -
Encode for Base64. -
encodeForBase64(byte[], boolean) - -Method in class org.owasp.esapi.reference.DefaultEncoder -
  -
encodeForCSS(String) - -Method in interface org.owasp.esapi.Encoder -
Encode data for use in Cascading Style Sheets (CSS) content. -
encodeForCSS(String) - -Method in class org.owasp.esapi.reference.DefaultEncoder -
http://www.w3.org/TR/CSS21/syndata.html#escaped-characters -
encodeForDN(String) - -Method in interface org.owasp.esapi.Encoder -
Encode data for use in an LDAP distinguished name. -
encodeForDN(String) - -Method in class org.owasp.esapi.reference.DefaultEncoder -
  -
encodeForHTML(String) - -Method in interface org.owasp.esapi.Encoder -
Encode data for use in HTML content. -
encodeForHTML(String) - -Method in class org.owasp.esapi.reference.DefaultEncoder -
Encode the input string using HTML entity encoding. -
encodeForHTMLAttribute(String) - -Method in interface org.owasp.esapi.Encoder -
Encode data for use in HTML attributes. -
encodeForHTMLAttribute(String) - -Method in class org.owasp.esapi.reference.DefaultEncoder -
  -
encodeForJavaScript(String) - -Method in interface org.owasp.esapi.Encoder -
Encode data for insertion inside a data value in JavaScript. -
encodeForJavaScript(String) - -Method in class org.owasp.esapi.reference.DefaultEncoder -
  -
encodeForLDAP(String) - -Method in interface org.owasp.esapi.Encoder -
Encode data for use in LDAP queries. -
encodeForLDAP(String) - -Method in class org.owasp.esapi.reference.DefaultEncoder -
  -
encodeForSQL(Codec, String) - -Method in interface org.owasp.esapi.Encoder -
Encode for SQL according to the selected codec. -
encodeForSQL(Codec, String) - -Method in class org.owasp.esapi.reference.DefaultEncoder -
This method is not recommended. -
encodeForURL(String) - -Method in interface org.owasp.esapi.Encoder -
Encode for use in a URL. -
encodeForURL(String) - -Method in class org.owasp.esapi.reference.DefaultEncoder -
  -
encodeForVBScript(String) - -Method in interface org.owasp.esapi.Encoder -
Encode data for insertion inside a data value in a visual basic script. -
encodeForVBScript(String) - -Method in class org.owasp.esapi.reference.DefaultEncoder -
  -
encodeForXML(String) - -Method in interface org.owasp.esapi.Encoder -
Encode data for use in an XML element. -
encodeForXML(String) - -Method in class org.owasp.esapi.reference.DefaultEncoder -
  -
encodeForXMLAttribute(String) - -Method in interface org.owasp.esapi.Encoder -
Encode data for use in an XML attribute. -
encodeForXMLAttribute(String) - -Method in class org.owasp.esapi.reference.DefaultEncoder -
  -
encodeForXPath(String) - -Method in interface org.owasp.esapi.Encoder -
Encode data for use in an XPath query. -
encodeForXPath(String) - -Method in class org.owasp.esapi.reference.DefaultEncoder -
This implementation encodes almost everything and may overencode. -
encodeFromFile(String) - -Static method in class org.owasp.esapi.codecs.Base64 -
Convenience method for reading a binary file - and base64-encoding it. -
encodeObject(Serializable) - -Static method in class org.owasp.esapi.codecs.Base64 -
Serializes an object and returns the Base64-encoded - version of that serialized object. -
encodeObject(Serializable, int) - -Static method in class org.owasp.esapi.codecs.Base64 -
Serializes an object and returns the Base64-encoded - version of that serialized object. -
encodeRedirectURL(String) - -Method in class org.owasp.esapi.filters.SafeResponse -
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. -
encodeRedirectURL(String) - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
encodeRedirectUrl(String) - -Method in class org.owasp.esapi.filters.SafeResponse -
Return the URL without any changes, to prevent disclosure of the - JSESSIONID. -
encodeRedirectUrl(String) - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
encodeToFile(byte[], String) - -Static method in class org.owasp.esapi.codecs.Base64 -
Convenience method for encoding data to a file. -
encodeURL(String) - -Method in class org.owasp.esapi.filters.SafeResponse -
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. -
encodeURL(String) - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
encodeUrl(String) - -Method in class org.owasp.esapi.filters.SafeResponse -
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. -
encodeUrl(String) - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
encoder() - -Static method in class org.owasp.esapi.ESAPI -
  -
encrypt(String) - -Method in interface org.owasp.esapi.Encryptor -
Encrypts the provided plaintext and returns a ciphertext string. -
encrypt(String) - -Method in class org.owasp.esapi.reference.JavaEncryptor -
  -
encryptHiddenField(String) - -Method in interface org.owasp.esapi.HTTPUtilities -
Encrypts a hidden field value for use in HTML. -
encryptHiddenField(String) - -Method in class org.owasp.esapi.reference.DefaultHTTPUtilities -
  -
encryptQueryString(String) - -Method in interface org.owasp.esapi.HTTPUtilities -
Takes a querystring (i.e. -
encryptQueryString(String) - -Method in class org.owasp.esapi.reference.DefaultHTTPUtilities -
  -
encryptStateInCookie(HttpServletResponse, Map) - -Method in interface org.owasp.esapi.HTTPUtilities -
Stores a Map of data in an encrypted cookie. -
encryptStateInCookie(HttpServletResponse, Map) - -Method in class org.owasp.esapi.reference.DefaultHTTPUtilities -
  -
encryptor() - -Static method in class org.owasp.esapi.ESAPI -
  -
error(String, String) - -Method in interface org.owasp.esapi.Logger -
Log error. -
error(String, String, Throwable) - -Method in interface org.owasp.esapi.Logger -
Log error. -
errors() - -Method in class org.owasp.esapi.ValidationErrorList -
Returns list of ValidationException, or empty list of no errors exist. -
executeSystemCommand(File, List, File, int) - -Method in interface org.owasp.esapi.Executor -
Executes a system command after checking that the executable exists and - that the parameters have not been subject to injection with untrusted - user data. -
executeSystemCommand(File, List, File, int) - -Method in class org.owasp.esapi.reference.DefaultExecutor -
  -
executor() - -Static method in class org.owasp.esapi.ESAPI -
  -
exists(String) - -Method in interface org.owasp.esapi.Authenticator -
Determine if the account exists. -
exists(String) - -Method in class org.owasp.esapi.reference.FileBasedAuthenticator -
  -
-
- - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
- - - diff --git a/javadoc/index-files/index-6.html b/javadoc/index-files/index-6.html deleted file mode 100644 index 84215fcf7..000000000 --- a/javadoc/index-files/index-6.html +++ /dev/null @@ -1,161 +0,0 @@ - - - - - - -F-Index - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
-

-F

-
-
FUNCTIONALITY - -Static variable in interface org.owasp.esapi.Logger -
  -
FileBasedAccessController - class org.owasp.esapi.reference.FileBasedAccessController.
Reference implementation of the AccessController interface.
FileBasedAccessController() - -Constructor for class org.owasp.esapi.reference.FileBasedAccessController -
  -
FileBasedAuthenticator - class org.owasp.esapi.reference.FileBasedAuthenticator.
Reference implementation of the Authenticator interface.
FileBasedAuthenticator() - -Constructor for class org.owasp.esapi.reference.FileBasedAuthenticator -
  -
fatal(String, String) - -Method in interface org.owasp.esapi.Logger -
Log critical. -
fatal(String, String, Throwable) - -Method in interface org.owasp.esapi.Logger -
Log critical. -
flushBase64() - -Method in class org.owasp.esapi.codecs.Base64.OutputStream -
Method added by PHIL. -
flushBuffer() - -Method in class org.owasp.esapi.filters.SafeResponse -
Same as HttpServletResponse, no security changes required. -
flushBuffer() - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
forward(ServletRequest, ServletResponse) - -Method in class org.owasp.esapi.http.TestRequestDispatcher -
  -
-
- - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
- - - diff --git a/javadoc/index-files/index-7.html b/javadoc/index-files/index-7.html deleted file mode 100644 index a04e2aaae..000000000 --- a/javadoc/index-files/index-7.html +++ /dev/null @@ -1,1075 +0,0 @@ - - - - - - -G-Index - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
-

-G

-
-
GZIP - -Static variable in class org.owasp.esapi.codecs.Base64 -
Specify that data should be gzip-compressed. -
generateStrongPassword() - -Method in interface org.owasp.esapi.Authenticator -
Generate a strong password. -
generateStrongPassword(User, String) - -Method in interface org.owasp.esapi.Authenticator -
Generate strong password that takes into account the user's information and old password. -
generateStrongPassword() - -Method in class org.owasp.esapi.reference.FileBasedAuthenticator -
  -
generateStrongPassword(User, String) - -Method in class org.owasp.esapi.reference.FileBasedAuthenticator -
  -
getAccountId() - -Method in interface org.owasp.esapi.User -
Gets the account id. -
getAccountId() - -Method in class org.owasp.esapi.reference.DefaultUser -
  -
getAccountName() - -Method in interface org.owasp.esapi.User -
Gets the account name. -
getAccountName() - -Method in class org.owasp.esapi.reference.DefaultUser -
Gets the account name. -
getAllowedFileExtensions() - -Method in interface org.owasp.esapi.SecurityConfiguration -
Gets the allowed file extensions. -
getAllowedFileExtensions() - -Method in class org.owasp.esapi.reference.DefaultSecurityConfiguration -
Gets the allowed file extensions. -
getAllowedFileUploadSize() - -Method in interface org.owasp.esapi.SecurityConfiguration -
Gets the allowed file upload size. -
getAllowedFileUploadSize() - -Method in class org.owasp.esapi.reference.DefaultSecurityConfiguration -
Gets the allowed file upload size. -
getAllowedLoginAttempts() - -Method in interface org.owasp.esapi.SecurityConfiguration -
Gets the allowed login attempts. -
getAllowedLoginAttempts() - -Method in class org.owasp.esapi.reference.DefaultSecurityConfiguration -
Gets the allowed login attempts. -
getApplicationName() - -Method in interface org.owasp.esapi.SecurityConfiguration -
Gets the application name, used for logging -
getApplicationName() - -Method in class org.owasp.esapi.reference.DefaultSecurityConfiguration -
  -
getAttribute(String) - -Method in class org.owasp.esapi.filters.SafeRequest -
Same as HttpServletRequest, no security changes required. -
getAttribute(String) - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getAttribute(String) - -Method in class org.owasp.esapi.http.TestHttpSession -
  -
getAttributeNames() - -Method in class org.owasp.esapi.filters.SafeRequest -
Same as HttpServletRequest, no security changes required. -
getAttributeNames() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getAttributeNames() - -Method in class org.owasp.esapi.http.TestHttpSession -
  -
getAuthType() - -Method in class org.owasp.esapi.filters.SafeRequest -
Same as HttpServletRequest, no security changes required. -
getAuthType() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getBufferSize() - -Method in class org.owasp.esapi.filters.SafeResponse -
Same as HttpServletResponse, no security changes required. -
getBufferSize() - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
getCSRFToken() - -Method in interface org.owasp.esapi.HTTPUtilities -
Returns the current user's CSRF token. -
getCSRFToken() - -Method in interface org.owasp.esapi.User -
Gets the CSRF token. -
getCSRFToken() - -Method in class org.owasp.esapi.reference.DefaultHTTPUtilities -
  -
getCSRFToken() - -Method in class org.owasp.esapi.reference.DefaultUser -
Gets the CSRF token. -
getCharacterEncoding() - -Method in interface org.owasp.esapi.SecurityConfiguration -
Gets the character encoding. -
getCharacterEncoding() - -Method in class org.owasp.esapi.filters.SafeRequest -
Same as HttpServletRequest, no security changes required. -
getCharacterEncoding() - -Method in class org.owasp.esapi.filters.SafeResponse -
Same as HttpServletResponse, no security changes required. -
getCharacterEncoding() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getCharacterEncoding() - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
getCharacterEncoding() - -Method in class org.owasp.esapi.reference.DefaultSecurityConfiguration -
Gets the character encoding. -
getContentLength() - -Method in class org.owasp.esapi.filters.SafeRequest -
Same as HttpServletRequest, no security changes required. -
getContentLength() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getContentType() - -Method in class org.owasp.esapi.filters.SafeRequest -
Same as HttpServletRequest, no security changes required. -
getContentType() - -Method in class org.owasp.esapi.filters.SafeResponse -
Same as HttpServletResponse, no security changes required. -
getContentType() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getContentType() - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
getContext() - -Method in class org.owasp.esapi.errors.ValidationException -
Returns the UI reference that caused this ValidationException -
getContextPath() - -Method in class org.owasp.esapi.filters.SafeRequest -
Returns the context path from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters. -
getContextPath() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getCookie(HttpServletRequest, String) - -Method in interface org.owasp.esapi.HTTPUtilities -
Get the first cookie with the matching name. -
getCookie(String) - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
getCookie(HttpServletRequest, String) - -Method in class org.owasp.esapi.reference.DefaultHTTPUtilities -
Returns the first cookie matching the provided name. -
getCookies() - -Method in class org.owasp.esapi.filters.SafeRequest -
Returns the array of Cookies from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters. -
getCookies() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getCookies() - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
Gets the cookies. -
getCreationTime() - -Method in class org.owasp.esapi.http.TestHttpSession -
  -
getCurrentRequest() - -Method in interface org.owasp.esapi.HTTPUtilities -
Retrieves the current HttpServletRequest -
getCurrentRequest() - -Method in class org.owasp.esapi.reference.DefaultHTTPUtilities -
  -
getCurrentResponse() - -Method in interface org.owasp.esapi.HTTPUtilities -
Retrieves the current HttpServletResponse -
getCurrentResponse() - -Method in class org.owasp.esapi.reference.DefaultHTTPUtilities -
  -
getCurrentUser() - -Method in interface org.owasp.esapi.Authenticator -
Returns the currently logged in User. -
getCurrentUser() - -Method in class org.owasp.esapi.reference.FileBasedAuthenticator -
  -
getDateHeader(String) - -Method in class org.owasp.esapi.filters.SafeRequest -
Same as HttpServletRequest, no security changes required. -
getDateHeader(String) - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getDigitalSignatureAlgorithm() - -Method in interface org.owasp.esapi.SecurityConfiguration -
Gets the digital signature algorithm. -
getDigitalSignatureAlgorithm() - -Method in class org.owasp.esapi.reference.DefaultSecurityConfiguration -
Gets the digital signature algorithm. -
getDirectReference(String) - -Method in interface org.owasp.esapi.AccessReferenceMap -
Get the original direct object reference from an indirect reference. -
getDirectReference(String) - -Method in class org.owasp.esapi.reference.IntegerAccessReferenceMap -
  -
getDirectReference(String) - -Method in class org.owasp.esapi.reference.RandomAccessReferenceMap -
  -
getEncryptionAlgorithm() - -Method in interface org.owasp.esapi.SecurityConfiguration -
Gets the encryption algorithm. -
getEncryptionAlgorithm() - -Method in class org.owasp.esapi.reference.DefaultSecurityConfiguration -
Gets the encryption algorithm. -
getError(String) - -Method in class org.owasp.esapi.ValidationErrorList -
Retrieves ValidationException for given context if one exists. -
getExpirationTime() - -Method in interface org.owasp.esapi.User -
Returns the date that the current user's account will expire, usually when the account will be disabled. -
getExpirationTime() - -Method in class org.owasp.esapi.reference.DefaultUser -
Gets the expiration time. -
getFailedLoginCount() - -Method in interface org.owasp.esapi.User -
Returns the number of failed login attempts since the last successful login for an account. -
getFailedLoginCount() - -Method in class org.owasp.esapi.reference.DefaultUser -
Gets the failed login count. -
getHashAlgorithm() - -Method in interface org.owasp.esapi.SecurityConfiguration -
Gets the hashing algorithm. -
getHashAlgorithm() - -Method in class org.owasp.esapi.reference.DefaultSecurityConfiguration -
Gets the hasing algorithm. -
getHeader(String) - -Method in class org.owasp.esapi.filters.SafeRequest -
Returns the named header from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters. -
getHeader(String) - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getHeader(String) - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
Gets the header. -
getHeaderNames() - -Method in class org.owasp.esapi.filters.SafeRequest -
Returns the enumeration of header names from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters. -
getHeaderNames() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getHeaderNames() - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
Gets the header names. -
getHeaders(String) - -Method in class org.owasp.esapi.filters.SafeRequest -
Returns the enumeration of headers from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters. -
getHeaders(String) - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getId() - -Method in class org.owasp.esapi.http.TestHttpSession -
  -
getIndirectReference(Object) - -Method in interface org.owasp.esapi.AccessReferenceMap -
Get a safe indirect reference to use in place of a potentially sensitive - direct object reference. -
getIndirectReference(Object) - -Method in class org.owasp.esapi.reference.IntegerAccessReferenceMap -
  -
getIndirectReference(Object) - -Method in class org.owasp.esapi.reference.RandomAccessReferenceMap -
  -
getInputStream() - -Method in class org.owasp.esapi.filters.SafeRequest -
Same as HttpServletRequest, no security changes required. -
getInputStream() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getIntHeader(String) - -Method in class org.owasp.esapi.filters.SafeRequest -
Same as HttpServletRequest, no security changes required. -
getIntHeader(String) - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getInvalidated() - -Method in class org.owasp.esapi.http.TestHttpSession -
Gets the invalidated. -
getKeystore() - -Method in interface org.owasp.esapi.SecurityConfiguration -
Gets the keystore. -
getKeystore() - -Method in class org.owasp.esapi.reference.DefaultSecurityConfiguration -
Gets the keystore. -
getLastAccessedTime() - -Method in class org.owasp.esapi.http.TestHttpSession -
  -
getLastFailedLoginTime() - -Method in interface org.owasp.esapi.User -
Returns the date of the last failed login time for a user. -
getLastFailedLoginTime() - -Method in class org.owasp.esapi.reference.DefaultUser -
Gets the last failed login time. -
getLastHostAddress() - -Method in interface org.owasp.esapi.User -
Returns the last host address used by the user. -
getLastHostAddress() - -Method in class org.owasp.esapi.reference.DefaultUser -
  -
getLastLoginTime() - -Method in interface org.owasp.esapi.User -
Returns the date of the last successful login time for a user. -
getLastLoginTime() - -Method in class org.owasp.esapi.reference.DefaultUser -
Gets the last login time. -
getLastPasswordChangeTime() - -Method in interface org.owasp.esapi.User -
Gets the date of user's last password change. -
getLastPasswordChangeTime() - -Method in class org.owasp.esapi.reference.DefaultUser -
Gets the last password change time. -
getLocalAddr() - -Method in class org.owasp.esapi.filters.SafeRequest -
Same as HttpServletRequest, no security changes required. -
getLocalAddr() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getLocalName() - -Method in class org.owasp.esapi.filters.SafeRequest -
Same as HttpServletRequest, no security changes required. -
getLocalName() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getLocalPort() - -Method in class org.owasp.esapi.filters.SafeRequest -
Same as HttpServletRequest, no security changes required. -
getLocalPort() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getLocale() - -Method in class org.owasp.esapi.filters.SafeRequest -
Same as HttpServletRequest, no security changes required. -
getLocale() - -Method in class org.owasp.esapi.filters.SafeResponse -
Same as HttpServletResponse, no security changes required. -
getLocale() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getLocale() - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
getLocales() - -Method in class org.owasp.esapi.filters.SafeRequest -
Same as HttpServletRequest, no security changes required. -
getLocales() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getLogEncodingRequired() - -Method in interface org.owasp.esapi.SecurityConfiguration -
Returns whether HTML entity encoding should be applied to log entries. -
getLogEncodingRequired() - -Method in class org.owasp.esapi.reference.DefaultSecurityConfiguration -
  -
getLogLevel() - -Method in class org.owasp.esapi.reference.DefaultSecurityConfiguration -
  -
getLogMessage() - -Method in class org.owasp.esapi.errors.EnterpriseSecurityException -
  -
getLogMessage() - -Method in class org.owasp.esapi.errors.IntrusionException -
  -
getLogger(Class) - -Static method in class org.owasp.esapi.ESAPI -
  -
getLogger(String) - -Static method in class org.owasp.esapi.ESAPI -
  -
getLogger(String) - -Method in interface org.owasp.esapi.LogFactory -
  -
getLogger(Class) - -Method in interface org.owasp.esapi.LogFactory -
  -
getLogger(Class) - -Method in class org.owasp.esapi.reference.JavaLogFactory -
  -
getLogger(String) - -Method in class org.owasp.esapi.reference.JavaLogFactory -
  -
getMasterPassword() - -Method in interface org.owasp.esapi.SecurityConfiguration -
Gets the master password. -
getMasterPassword() - -Method in class org.owasp.esapi.reference.DefaultSecurityConfiguration -
Gets the master password. -
getMasterSalt() - -Method in interface org.owasp.esapi.SecurityConfiguration -
Gets the master salt. -
getMasterSalt() - -Method in class org.owasp.esapi.reference.DefaultSecurityConfiguration -
Gets the master salt. -
getMaxInactiveInterval() - -Method in class org.owasp.esapi.http.TestHttpSession -
  -
getMaxOldPasswordHashes() - -Method in interface org.owasp.esapi.SecurityConfiguration -
Gets the max old password hashes. -
getMaxOldPasswordHashes() - -Method in class org.owasp.esapi.reference.DefaultSecurityConfiguration -
Gets the max old password hashes. -
getMethod() - -Method in class org.owasp.esapi.filters.SafeRequest -
Same as HttpServletRequest, no security changes required. -
getMethod() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getName() - -Method in class org.owasp.esapi.reference.DefaultUser -
  -
getName() - -Method in class org.owasp.esapi.tags.EncodeForHTMLAttributeTag -
  -
getName() - -Method in class org.owasp.esapi.tags.EncodeForHTMLJavaScriptTag -
  -
getName() - -Method in class org.owasp.esapi.tags.EncodeForHTMLTag -
  -
getName() - -Method in class org.owasp.esapi.tags.EncodeForVBScriptTag -
  -
getOutputStream() - -Method in class org.owasp.esapi.filters.SafeResponse -
Same as HttpServletResponse, no security changes required. -
getOutputStream() - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
getParameter(String) - -Method in class org.owasp.esapi.filters.SafeRequest -
Returns the named parameter from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters. -
getParameter(String) - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getParameterMap() - -Method in class org.owasp.esapi.filters.SafeRequest -
Returns the parameter map from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters. -
getParameterMap() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getParameterNames() - -Method in class org.owasp.esapi.filters.SafeRequest -
Returns the enumeration of parameter names from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters. -
getParameterNames() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getParameterValues(String) - -Method in class org.owasp.esapi.filters.SafeRequest -
Returns the array of matching parameter values from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters. -
getParameterValues(String) - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getPasswordParameterName() - -Method in interface org.owasp.esapi.SecurityConfiguration -
Gets the password parameter name. -
getPasswordParameterName() - -Method in class org.owasp.esapi.reference.DefaultSecurityConfiguration -
Gets the password parameter name. -
getPathInfo() - -Method in class org.owasp.esapi.filters.SafeRequest -
Returns the path info from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters. -
getPathInfo() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getPathTranslated() - -Method in class org.owasp.esapi.filters.SafeRequest -
Same as HttpServletRequest, no security changes required. -
getPathTranslated() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getProperty(String) - -Method in interface org.owasp.esapi.EncryptedProperties -
Gets the property value from the encrypted store, decrypts it, and returns the plaintext value to the caller. -
getProperty(String) - -Method in class org.owasp.esapi.reference.DefaultEncryptedProperties -
  -
getProtocol() - -Method in class org.owasp.esapi.filters.SafeRequest -
Same as HttpServletRequest, no security changes required. -
getProtocol() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getQueryString() - -Method in class org.owasp.esapi.filters.SafeRequest -
Returns the query string from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters. -
getQueryString() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getQuota(String) - -Method in interface org.owasp.esapi.SecurityConfiguration -
Gets an intrusion detection Quota. -
getQuota(String) - -Method in class org.owasp.esapi.reference.DefaultSecurityConfiguration -
  -
getRandomAlgorithm() - -Method in interface org.owasp.esapi.SecurityConfiguration -
Gets the random number generation algorithm. -
getRandomAlgorithm() - -Method in class org.owasp.esapi.reference.DefaultSecurityConfiguration -
Gets the random number generation algorithm. -
getRandomBoolean() - -Method in interface org.owasp.esapi.Randomizer -
Returns a random boolean. -
getRandomBoolean() - -Method in class org.owasp.esapi.reference.DefaultRandomizer -
  -
getRandomFilename(String) - -Method in interface org.owasp.esapi.Randomizer -
Returns an unguessable random filename with the specified extension. -
getRandomFilename(String) - -Method in class org.owasp.esapi.reference.DefaultRandomizer -
Returns an unguessable random filename with the specified extension. -
getRandomGUID() - -Method in interface org.owasp.esapi.Randomizer -
Generates a random GUID. -
getRandomGUID() - -Method in class org.owasp.esapi.reference.DefaultRandomizer -
  -
getRandomInteger(int, int) - -Method in interface org.owasp.esapi.Randomizer -
Gets the random integer. -
getRandomInteger(int, int) - -Method in class org.owasp.esapi.reference.DefaultRandomizer -
(non-Javadoc) -
getRandomLong() - -Method in interface org.owasp.esapi.Randomizer -
Gets the random long. -
getRandomLong() - -Method in class org.owasp.esapi.reference.DefaultRandomizer -
(non-Javadoc) -
getRandomReal(float, float) - -Method in interface org.owasp.esapi.Randomizer -
Gets the random real. -
getRandomReal(float, float) - -Method in class org.owasp.esapi.reference.DefaultRandomizer -
  -
getRandomString(int, char[]) - -Method in interface org.owasp.esapi.Randomizer -
Gets a random string. -
getRandomString(int, char[]) - -Method in class org.owasp.esapi.reference.DefaultRandomizer -
  -
getReader() - -Method in class org.owasp.esapi.filters.SafeRequest -
Same as HttpServletRequest, no security changes required. -
getReader() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getRealPath(String) - -Method in class org.owasp.esapi.filters.SafeRequest -
Same as HttpServletRequest, no security changes required. -
getRealPath(String) - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getRelativeTimeStamp(long) - -Method in interface org.owasp.esapi.Encryptor -
Gets an absolute timestamp representing an offset from the current time to be used by - other functions in the library. -
getRelativeTimeStamp(long) - -Method in class org.owasp.esapi.reference.JavaEncryptor -
  -
getRememberTokenDuration() - -Method in interface org.owasp.esapi.SecurityConfiguration -
Gets the time window allowed for the remember token in milliseconds. -
getRememberTokenDuration() - -Method in class org.owasp.esapi.reference.DefaultSecurityConfiguration -
  -
getRemoteAddr() - -Method in class org.owasp.esapi.filters.SafeRequest -
Same as HttpServletRequest, no security changes required. -
getRemoteAddr() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getRemoteHost() - -Method in class org.owasp.esapi.filters.SafeRequest -
Same as HttpServletRequest, no security changes required. -
getRemoteHost() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getRemotePort() - -Method in class org.owasp.esapi.filters.SafeRequest -
Same as HttpServletRequest, no security changes required. -
getRemotePort() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getRemoteUser() - -Method in class org.owasp.esapi.filters.SafeRequest -
Returns the name of the ESAPI user associated with this request. -
getRemoteUser() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getRequestDispatcher(String) - -Method in class org.owasp.esapi.filters.SafeRequest -
Checks to make sure the path to forward to is within the WEB-INF directory - and then returns the dispatcher. -
getRequestDispatcher(String) - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getRequestURI() - -Method in class org.owasp.esapi.filters.SafeRequest -
Returns the URI from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters. -
getRequestURI() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getRequestURL() - -Method in class org.owasp.esapi.filters.SafeRequest -
Returns the URL from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters. -
getRequestURL() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getRequestedSessionId() - -Method in class org.owasp.esapi.filters.SafeRequest -
Returns the URI from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters. -
getRequestedSessionId() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getResourceDirectory() - -Method in interface org.owasp.esapi.SecurityConfiguration -
Gets the ESAPI resource directory as a String. -
getResourceDirectory() - -Method in class org.owasp.esapi.reference.DefaultSecurityConfiguration -
Gets the resource directory. -
getResponseContentType() - -Method in interface org.owasp.esapi.SecurityConfiguration -
Gets the content-type set for responses. -
getResponseContentType() - -Method in class org.owasp.esapi.reference.DefaultSecurityConfiguration -
  -
getRoles() - -Method in interface org.owasp.esapi.User -
Gets the roles assigned to a particular account. -
getRoles() - -Method in class org.owasp.esapi.reference.DefaultUser -
Gets the roles. -
getSafeFileUploads(HttpServletRequest, File, File) - -Method in interface org.owasp.esapi.HTTPUtilities -
Extract uploaded files from a multipart HTTP requests. -
getSafeFileUploads(HttpServletRequest, File, File) - -Method in class org.owasp.esapi.reference.DefaultHTTPUtilities -
Uses the Apache Commons FileUploader to parse the multipart HTTP request - and extract any files therein. -
getScheme() - -Method in class org.owasp.esapi.filters.SafeRequest -
Returns the scheme from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters. -
getScheme() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getScreenName() - -Method in interface org.owasp.esapi.User -
Gets the screen name. -
getScreenName() - -Method in class org.owasp.esapi.reference.DefaultUser -
  -
getSerialVersionUID() - -Static method in class org.owasp.esapi.errors.ValidationException -
  -
getServerName() - -Method in class org.owasp.esapi.filters.SafeRequest -
Returns the server name (host header) from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters. -
getServerName() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getServerPort() - -Method in class org.owasp.esapi.filters.SafeRequest -
Returns the server port (after the : in the host header) from the HttpServletRequest after - parsing and checking the range 0-65536. -
getServerPort() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getServletContext() - -Method in class org.owasp.esapi.http.TestHttpSession -
  -
getServletPath() - -Method in class org.owasp.esapi.filters.SafeRequest -
Returns the server path from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters. -
getServletPath() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getSession() - -Method in class org.owasp.esapi.filters.SafeRequest -
Returns a session, creating it if necessary, and sets the HttpOnly flag on the JSESSIONID cookie. -
getSession(boolean) - -Method in class org.owasp.esapi.filters.SafeRequest -
Returns a session, creating it if necessary, and sets the HttpOnly flag on the JSESSIONID cookie. -
getSession() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getSession(boolean) - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getSessionContext() - -Method in class org.owasp.esapi.http.TestHttpSession -
  -
getStatus() - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
Gets the status. -
getTimeStamp() - -Method in interface org.owasp.esapi.Encryptor -
Gets a timestamp representing the current date and time to be used by - other functions in the library. -
getTimeStamp() - -Method in class org.owasp.esapi.reference.JavaEncryptor -
  -
getUser(long) - -Method in interface org.owasp.esapi.Authenticator -
Returns the User matching the provided accountId. -
getUser(String) - -Method in interface org.owasp.esapi.Authenticator -
Returns the User matching the provided accountName. -
getUser(long) - -Method in class org.owasp.esapi.reference.FileBasedAuthenticator -
Gets the user object with the matching account name or null if there is no match. -
getUser(String) - -Method in class org.owasp.esapi.reference.FileBasedAuthenticator -
Gets the user object with the matching account name or null if there is no match. -
getUserMessage() - -Method in class org.owasp.esapi.errors.EnterpriseSecurityException -
  -
getUserMessage() - -Method in class org.owasp.esapi.errors.IntrusionException -
  -
getUserNames() - -Method in interface org.owasp.esapi.Authenticator -
Gets a collection containing all the existing user names. -
getUserNames() - -Method in class org.owasp.esapi.reference.FileBasedAuthenticator -
Gets the user names. -
getUserPrincipal() - -Method in class org.owasp.esapi.filters.SafeRequest -
Returns the ESAPI User associated with this request. -
getUserPrincipal() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
getUsernameParameterName() - -Method in interface org.owasp.esapi.SecurityConfiguration -
Gets the username parameter name. -
getUsernameParameterName() - -Method in class org.owasp.esapi.reference.DefaultSecurityConfiguration -
Gets the username parameter name. -
getValidCreditCard(String, String, boolean) - -Method in interface org.owasp.esapi.Validator -
Returns a canonicalized and validated credit card number as a String. -
getValidCreditCard(String, String, boolean, ValidationErrorList) - -Method in interface org.owasp.esapi.Validator -
Returns a canonicalized and validated credit card number as a String. -
getValidCreditCard(String, String, boolean) - -Method in class org.owasp.esapi.reference.DefaultValidator -
Returns a canonicalized and validated credit card number as a String. -
getValidCreditCard(String, String, boolean, ValidationErrorList) - -Method in class org.owasp.esapi.reference.DefaultValidator -
ValidationErrorList variant of getValidCreditCard -
getValidDate(String, String, DateFormat, boolean) - -Method in interface org.owasp.esapi.Validator -
Returns a valid date as a Date. -
getValidDate(String, String, DateFormat, boolean, ValidationErrorList) - -Method in interface org.owasp.esapi.Validator -
Returns a valid date as a Date. -
getValidDate(String, String, DateFormat, boolean) - -Method in class org.owasp.esapi.reference.DefaultValidator -
  -
getValidDate(String, String, DateFormat, boolean, ValidationErrorList) - -Method in class org.owasp.esapi.reference.DefaultValidator -
  -
getValidDirectoryPath(String, String, boolean) - -Method in interface org.owasp.esapi.Validator -
Returns a canonicalized and validated directory path as a String. -
getValidDirectoryPath(String, String, boolean, ValidationErrorList) - -Method in interface org.owasp.esapi.Validator -
Returns a canonicalized and validated directory path as a String. -
getValidDirectoryPath(String, String, boolean) - -Method in class org.owasp.esapi.reference.DefaultValidator -
Returns a canonicalized and validated directory path as a String. -
getValidDirectoryPath(String, String, boolean, ValidationErrorList) - -Method in class org.owasp.esapi.reference.DefaultValidator -
ValidationErrorList variant of getValidDirectoryPath -
getValidDouble(String, String, double, double, boolean) - -Method in interface org.owasp.esapi.Validator -
Returns a validated real number as a double. -
getValidDouble(String, String, double, double, boolean, ValidationErrorList) - -Method in interface org.owasp.esapi.Validator -
Returns a validated real number as a double. -
getValidDouble(String, String, double, double, boolean) - -Method in class org.owasp.esapi.reference.DefaultValidator -
Returns a validated number as a double. -
getValidDouble(String, String, double, double, boolean, ValidationErrorList) - -Method in class org.owasp.esapi.reference.DefaultValidator -
  -
getValidFileContent(String, byte[], int, boolean) - -Method in interface org.owasp.esapi.Validator -
Returns validated file content as a byte array. -
getValidFileContent(String, byte[], int, boolean, ValidationErrorList) - -Method in interface org.owasp.esapi.Validator -
Returns validated file content as a byte array. -
getValidFileContent(String, byte[], int, boolean) - -Method in class org.owasp.esapi.reference.DefaultValidator -
Returns validated file content as a byte array. -
getValidFileContent(String, byte[], int, boolean, ValidationErrorList) - -Method in class org.owasp.esapi.reference.DefaultValidator -
  -
getValidFileName(String, String, boolean) - -Method in interface org.owasp.esapi.Validator -
Returns a canonicalized and validated file name as a String. -
getValidFileName(String, String, boolean, ValidationErrorList) - -Method in interface org.owasp.esapi.Validator -
Returns a canonicalized and validated file name as a String. -
getValidFileName(String, String, boolean) - -Method in class org.owasp.esapi.reference.DefaultValidator -
Returns a canonicalized and validated file name as a String. -
getValidFileName(String, String, boolean, ValidationErrorList) - -Method in class org.owasp.esapi.reference.DefaultValidator -
Returns a canonicalized and validated file name as a String. -
getValidInput(String, String, String, int, boolean) - -Method in interface org.owasp.esapi.Validator -
Returns canonicalized and validated input as a String. -
getValidInput(String, String, String, int, boolean, ValidationErrorList) - -Method in interface org.owasp.esapi.Validator -
Returns canonicalized and validated input as a String. -
getValidInput(String, String, String, int, boolean) - -Method in class org.owasp.esapi.reference.DefaultValidator -
Validates data received from the browser and returns a safe version. -
getValidInput(String, String, String, int, boolean, ValidationErrorList) - -Method in class org.owasp.esapi.reference.DefaultValidator -
Validates data received from the browser and returns a safe version. -
getValidInteger(String, String, int, int, boolean) - -Method in interface org.owasp.esapi.Validator -
Returns a validated integer. -
getValidInteger(String, String, int, int, boolean, ValidationErrorList) - -Method in interface org.owasp.esapi.Validator -
Returns a validated integer. -
getValidInteger(String, String, int, int, boolean) - -Method in class org.owasp.esapi.reference.DefaultValidator -
Returns a validated number as a double. -
getValidInteger(String, String, int, int, boolean, ValidationErrorList) - -Method in class org.owasp.esapi.reference.DefaultValidator -
  -
getValidListItem(String, String, List) - -Method in interface org.owasp.esapi.Validator -
Returns the list item that exactly matches the canonicalized input. -
getValidListItem(String, String, List, ValidationErrorList) - -Method in interface org.owasp.esapi.Validator -
Returns the list item that exactly matches the canonicalized input. -
getValidListItem(String, String, List) - -Method in class org.owasp.esapi.reference.DefaultValidator -
Returns the list item that exactly matches the canonicalized input. -
getValidListItem(String, String, List, ValidationErrorList) - -Method in class org.owasp.esapi.reference.DefaultValidator -
ValidationErrorList variant of getValidListItem -
getValidNumber(String, String, long, long, boolean) - -Method in interface org.owasp.esapi.Validator -
Returns a validated number as a double within the range of minValue to maxValue. -
getValidNumber(String, String, long, long, boolean, ValidationErrorList) - -Method in interface org.owasp.esapi.Validator -
Returns a validated number as a double within the range of minValue to maxValue. -
getValidNumber(String, String, long, long, boolean) - -Method in class org.owasp.esapi.reference.DefaultValidator -
Returns a validated number as a double. -
getValidNumber(String, String, long, long, boolean, ValidationErrorList) - -Method in class org.owasp.esapi.reference.DefaultValidator -
  -
getValidPrintable(String, byte[], int, boolean) - -Method in interface org.owasp.esapi.Validator -
Returns canonicalized and validated printable characters as a byte array. -
getValidPrintable(String, byte[], int, boolean, ValidationErrorList) - -Method in interface org.owasp.esapi.Validator -
Returns canonicalized and validated printable characters as a byte array. -
getValidPrintable(String, String, int, boolean) - -Method in interface org.owasp.esapi.Validator -
Returns canonicalized and validated printable characters as a String. -
getValidPrintable(String, String, int, boolean, ValidationErrorList) - -Method in interface org.owasp.esapi.Validator -
Returns canonicalized and validated printable characters as a String. -
getValidPrintable(String, byte[], int, boolean) - -Method in class org.owasp.esapi.reference.DefaultValidator -
Returns canonicalized and validated printable characters as a byte array. -
getValidPrintable(String, byte[], int, boolean, ValidationErrorList) - -Method in class org.owasp.esapi.reference.DefaultValidator -
ValidationErrorList variant of getValidPrintable -
getValidPrintable(String, String, int, boolean) - -Method in class org.owasp.esapi.reference.DefaultValidator -
Returns canonicalized and validated printable characters as a String. -
getValidPrintable(String, String, int, boolean, ValidationErrorList) - -Method in class org.owasp.esapi.reference.DefaultValidator -
ValidationErrorList variant of getValidPrintable -
getValidRedirectLocation(String, String, boolean) - -Method in interface org.owasp.esapi.Validator -
Returns a canonicalized and validated redirect location as a String. -
getValidRedirectLocation(String, String, boolean, ValidationErrorList) - -Method in interface org.owasp.esapi.Validator -
Returns a canonicalized and validated redirect location as a String. -
getValidRedirectLocation(String, String, boolean) - -Method in class org.owasp.esapi.reference.DefaultValidator -
Returns a canonicalized and validated redirect location as a String. -
getValidRedirectLocation(String, String, boolean, ValidationErrorList) - -Method in class org.owasp.esapi.reference.DefaultValidator -
ValidationErrorList variant of getValidRedirectLocation -
getValidSafeHTML(String, String, int, boolean) - -Method in interface org.owasp.esapi.Validator -
Returns canonicalized and validated "safe" HTML. -
getValidSafeHTML(String, String, int, boolean, ValidationErrorList) - -Method in interface org.owasp.esapi.Validator -
Returns canonicalized and validated "safe" HTML. -
getValidSafeHTML(String, String, int, boolean) - -Method in class org.owasp.esapi.reference.DefaultValidator -
  -
getValidSafeHTML(String, String, int, boolean, ValidationErrorList) - -Method in class org.owasp.esapi.reference.DefaultValidator -
ValidationErrorList variant of getValidSafeHTML -
getValidationPattern(String) - -Method in class org.owasp.esapi.reference.DefaultSecurityConfiguration -
  -
getValidationPatternNames() - -Method in class org.owasp.esapi.reference.DefaultSecurityConfiguration -
  -
getValue(String) - -Method in class org.owasp.esapi.http.TestHttpSession -
  -
getValueNames() - -Method in class org.owasp.esapi.http.TestHttpSession -
  -
getWriter() - -Method in class org.owasp.esapi.filters.SafeResponse -
Same as HttpServletResponse, no security changes required. -
getWriter() - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
-
- - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
- - - diff --git a/javadoc/index-files/index-8.html b/javadoc/index-files/index-8.html deleted file mode 100644 index 43b74cf27..000000000 --- a/javadoc/index-files/index-8.html +++ /dev/null @@ -1,161 +0,0 @@ - - - - - - -H-Index - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
-

-H

-
-
HTMLEntityCodec - class org.owasp.esapi.codecs.HTMLEntityCodec.
Implementation of the Codec interface for HTML entity encoding.
HTMLEntityCodec() - -Constructor for class org.owasp.esapi.codecs.HTMLEntityCodec -
  -
HTTPUtilities - interface org.owasp.esapi.HTTPUtilities.
The HTTPUtilities interface is a collection of methods that provide additional security related to HTTP requests, - responses, sessions, cookies, headers, and logging.
HTTPUtilitiesTest - class org.owasp.esapi.reference.HTTPUtilitiesTest.
The Class HTTPUtilitiesTest.
HTTPUtilitiesTest(String) - -Constructor for class org.owasp.esapi.reference.HTTPUtilitiesTest -
Instantiates a new HTTP utilities test. -
hasNext() - -Method in class org.owasp.esapi.codecs.PushbackString -
  -
hash(String, String) - -Method in interface org.owasp.esapi.Encryptor -
Returns a string representation of the hash of the provided plaintext and - salt. -
hash(String, String) - -Method in class org.owasp.esapi.reference.JavaEncryptor -
Hashes the data using the specified algorithm and the Java MessageDigest class. -
hashPassword(String, String) - -Method in interface org.owasp.esapi.Authenticator -
Returns a string representation of the hashed password, using the - accountName as the salt. -
hashPassword(String, String) - -Method in class org.owasp.esapi.reference.FileBasedAuthenticator -
  -
httpUtilities() - -Static method in class org.owasp.esapi.ESAPI -
  -
-
- - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
- - - diff --git a/javadoc/index-files/index-9.html b/javadoc/index-files/index-9.html deleted file mode 100644 index 53de06281..000000000 --- a/javadoc/index-files/index-9.html +++ /dev/null @@ -1,473 +0,0 @@ - - - - - - -I-Index - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
-

-I

-
-
IntegerAccessReferenceMap - class org.owasp.esapi.reference.IntegerAccessReferenceMap.
Reference implementation of the AccessReferenceMap interface.
IntegerAccessReferenceMap() - -Constructor for class org.owasp.esapi.reference.IntegerAccessReferenceMap -
This AccessReferenceMap implementation uses integers to - create a layer of indirection. -
IntegerAccessReferenceMap(Set) - -Constructor for class org.owasp.esapi.reference.IntegerAccessReferenceMap -
Instantiates a new access reference map. -
IntegerAccessReferenceMapTest - class org.owasp.esapi.reference.IntegerAccessReferenceMapTest.
The Class AccessReferenceMapTest.
IntegerAccessReferenceMapTest(String) - -Constructor for class org.owasp.esapi.reference.IntegerAccessReferenceMapTest -
Instantiates a new access reference map test. -
IntegrityException - exception org.owasp.esapi.errors.IntegrityException.
An AvailabilityException should be thrown when the availability of a limited - resource is in jeopardy.
IntegrityException(String, String) - -Constructor for class org.owasp.esapi.errors.IntegrityException -
Creates a new instance of IntegrityException. -
IntegrityException(String, String, Throwable) - -Constructor for class org.owasp.esapi.errors.IntegrityException -
Instantiates a new IntegrityException. -
IntrusionDetector - interface org.owasp.esapi.IntrusionDetector.
The IntrusionDetector interface is intended to track security relevant events and identify attack behavior.
IntrusionDetectorTest - class org.owasp.esapi.reference.IntrusionDetectorTest.
The Class IntrusionDetectorTest.
IntrusionDetectorTest(String) - -Constructor for class org.owasp.esapi.reference.IntrusionDetectorTest -
Instantiates a new intrusion detector test. -
IntrusionException - exception org.owasp.esapi.errors.IntrusionException.
An IntrusionException should be thrown anytime an error condition arises that is likely to be the result of an attack - in progress.
IntrusionException(String, String) - -Constructor for class org.owasp.esapi.errors.IntrusionException -
Creates a new instance of IntrusionException. -
IntrusionException(String, String, Throwable) - -Constructor for class org.owasp.esapi.errors.IntrusionException -
Instantiates a new intrusion exception. -
include(ServletRequest, ServletResponse) - -Method in class org.owasp.esapi.http.TestRequestDispatcher -
  -
incrementFailedLoginCount() - -Method in interface org.owasp.esapi.User -
Increment failed login count. -
incrementFailedLoginCount() - -Method in class org.owasp.esapi.reference.DefaultUser -
  -
index() - -Method in class org.owasp.esapi.codecs.PushbackString -
  -
info(String, String) - -Method in interface org.owasp.esapi.Logger -
Log success. -
info(String, String, Throwable) - -Method in interface org.owasp.esapi.Logger -
Log success. -
init(FilterConfig) - -Method in class org.owasp.esapi.filters.ESAPIFilter -
Called by the web container to indicate to a filter that it is being - placed into service. -
init(FilterConfig) - -Method in class org.owasp.esapi.filters.SafeHTTPFilter -
  -
interval - -Variable in class org.owasp.esapi.SecurityConfiguration.Threshold -
  -
intrusionDetector() - -Static method in class org.owasp.esapi.ESAPI -
  -
invalidate() - -Method in class org.owasp.esapi.http.TestHttpSession -
  -
isAnonymous() - -Method in interface org.owasp.esapi.User -
Checks if user is anonymous. -
isAnonymous() - -Method in class org.owasp.esapi.reference.DefaultUser -
  -
isAuthorizedForData(String) - -Method in interface org.owasp.esapi.AccessController -
Checks if an account is authorized to access the referenced data. -
isAuthorizedForData(String) - -Method in class org.owasp.esapi.reference.FileBasedAccessController -
  -
isAuthorizedForFile(String) - -Method in interface org.owasp.esapi.AccessController -
Checks if an account is authorized to access the referenced file. -
isAuthorizedForFile(String) - -Method in class org.owasp.esapi.reference.FileBasedAccessController -
  -
isAuthorizedForFunction(String) - -Method in interface org.owasp.esapi.AccessController -
Checks if an account is authorized to access the referenced function. -
isAuthorizedForFunction(String) - -Method in class org.owasp.esapi.reference.FileBasedAccessController -
  -
isAuthorizedForService(String) - -Method in interface org.owasp.esapi.AccessController -
Checks if an account is authorized to access the referenced service. -
isAuthorizedForService(String) - -Method in class org.owasp.esapi.reference.FileBasedAccessController -
  -
isAuthorizedForURL(String) - -Method in interface org.owasp.esapi.AccessController -
Checks if an account is authorized to access the referenced URL. -
isAuthorizedForURL(String) - -Method in class org.owasp.esapi.reference.FileBasedAccessController -
  -
isCommitted() - -Method in class org.owasp.esapi.filters.SafeResponse -
Same as HttpServletResponse, no security changes required. -
isCommitted() - -Method in class org.owasp.esapi.http.TestHttpServletResponse -
  -
isDebugEnabled() - -Method in interface org.owasp.esapi.Logger -
Allows the caller to determine if messages logged at this level - will be discarded, to avoid performing expensive processing -
isEmpty() - -Method in class org.owasp.esapi.ValidationErrorList -
Returns true if no error are present. -
isEnabled() - -Method in interface org.owasp.esapi.User -
Checks if an account is currently enabled. -
isEnabled() - -Method in class org.owasp.esapi.reference.DefaultUser -
Checks if is enabled. -
isErrorEnabled() - -Method in interface org.owasp.esapi.Logger -
Allows the caller to determine if messages logged at this level - will be discarded, to avoid performing expensive processing -
isExpired() - -Method in interface org.owasp.esapi.User -
Checks if an account is expired. -
isExpired() - -Method in class org.owasp.esapi.reference.DefaultUser -
  -
isFatalEnabled() - -Method in interface org.owasp.esapi.Logger -
Allows the caller to determine if messages logged at this level - will be discarded, to avoid performing expensive processing -
isHexDigit(Character) - -Method in class org.owasp.esapi.codecs.PushbackString -
  -
isInRole(String) - -Method in interface org.owasp.esapi.User -
Checks if an account has been assigned a particular role. -
isInRole(String) - -Method in class org.owasp.esapi.reference.DefaultUser -
  -
isInfoEnabled() - -Method in interface org.owasp.esapi.Logger -
Allows the caller to determine if messages logged at this level - will be discarded, to avoid performing expensive processing -
isLocked() - -Method in interface org.owasp.esapi.User -
Checks if an account is locked. -
isLocked() - -Method in class org.owasp.esapi.reference.DefaultUser -
  -
isLoggedIn() - -Method in interface org.owasp.esapi.User -
Tests to see if the user is currently logged in. -
isLoggedIn() - -Method in class org.owasp.esapi.reference.DefaultUser -
  -
isNew() - -Method in class org.owasp.esapi.http.TestHttpSession -
  -
isPushback() - -Method in class org.owasp.esapi.codecs.PushbackString -
  -
isRequestedSessionIdFromCookie() - -Method in class org.owasp.esapi.filters.SafeRequest -
Same as HttpServletRequest, no security changes required. -
isRequestedSessionIdFromCookie() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
isRequestedSessionIdFromURL() - -Method in class org.owasp.esapi.filters.SafeRequest -
Same as HttpServletRequest, no security changes required. -
isRequestedSessionIdFromURL() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
isRequestedSessionIdFromUrl() - -Method in class org.owasp.esapi.filters.SafeRequest -
Same as HttpServletRequest, no security changes required. -
isRequestedSessionIdFromUrl() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
isRequestedSessionIdValid() - -Method in class org.owasp.esapi.filters.SafeRequest -
Same as HttpServletRequest, no security changes required. -
isRequestedSessionIdValid() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
isSecure() - -Method in class org.owasp.esapi.filters.SafeRequest -
Same as HttpServletRequest, no security changes required. -
isSecure() - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
isSecureChannel(HttpServletRequest) - -Method in class org.owasp.esapi.reference.DefaultHTTPUtilities -
Returns true if the request was transmitted over an SSL enabled - connection. -
isSessionAbsoluteTimeout() - -Method in interface org.owasp.esapi.User -
Tests to see if the user's session has exceeded the absolute time out. -
isSessionAbsoluteTimeout() - -Method in class org.owasp.esapi.reference.DefaultUser -
  -
isSessionTimeout() - -Method in interface org.owasp.esapi.User -
Tests to see if the user's session has timed out from inactivity. -
isSessionTimeout() - -Method in class org.owasp.esapi.reference.DefaultUser -
  -
isTraceEnabled() - -Method in interface org.owasp.esapi.Logger -
Allows the caller to determine if messages logged at this level - will be discarded, to avoid performing expensive processing -
isUserInRole(String) - -Method in class org.owasp.esapi.filters.SafeRequest -
Returns true if the ESAPI User associated with this request has the specified role. -
isUserInRole(String) - -Method in class org.owasp.esapi.http.TestHttpServletRequest -
  -
isValidCreditCard(String, String, boolean) - -Method in interface org.owasp.esapi.Validator -
Returns true if input is a valid credit card. -
isValidCreditCard(String, String, boolean) - -Method in class org.owasp.esapi.reference.DefaultValidator -
  -
isValidDate(String, String, DateFormat, boolean) - -Method in interface org.owasp.esapi.Validator -
Returns true if input is a valid date according to the specified date format. -
isValidDate(String, String, DateFormat, boolean) - -Method in class org.owasp.esapi.reference.DefaultValidator -
Returns true if input is a valid date according to the specified date format. -
isValidDirectoryPath(String, String, boolean) - -Method in interface org.owasp.esapi.Validator -
Returns true if input is a valid directory path. -
isValidDirectoryPath(String, String, boolean) - -Method in class org.owasp.esapi.reference.DefaultValidator -
Returns true if the directory path (not including a filename) is valid. -
isValidDouble(String, String, double, double, boolean) - -Method in interface org.owasp.esapi.Validator -
Returns true if input is a valid double within the range of minValue to maxValue. -
isValidDouble(String, String, double, double, boolean) - -Method in class org.owasp.esapi.reference.DefaultValidator -
  -
isValidFileContent(String, byte[], int, boolean) - -Method in interface org.owasp.esapi.Validator -
Returns true if input is valid file content. -
isValidFileContent(String, byte[], int, boolean) - -Method in class org.owasp.esapi.reference.DefaultValidator -
Returns true if input is valid file content. -
isValidFileName(String, String, boolean) - -Method in interface org.owasp.esapi.Validator -
Returns true if input is a valid file name. -
isValidFileName(String, String, boolean) - -Method in class org.owasp.esapi.reference.DefaultValidator -
Returns true if input is a valid file name. -
isValidFileUpload(String, String, String, byte[], int, boolean) - -Method in interface org.owasp.esapi.Validator -
Returns true if a file upload has a valid name, path, and content. -
isValidFileUpload(String, String, String, byte[], int, boolean) - -Method in class org.owasp.esapi.reference.DefaultValidator -
Returns true if a file upload has a valid name, path, and content. -
isValidHTTPRequest() - -Method in interface org.owasp.esapi.Validator -
Validate the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed - characters. -
isValidHTTPRequest() - -Method in class org.owasp.esapi.reference.DefaultValidator -
Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed - characters. -
isValidHTTPRequest(HttpServletRequest) - -Method in class org.owasp.esapi.reference.DefaultValidator -
Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed - characters. -
isValidHTTPRequestParameterSet(String, Set, Set) - -Method in interface org.owasp.esapi.Validator -
Returns true if the parameters in the current request contain all required parameters and only optional ones in addition. -
isValidHTTPRequestParameterSet(String, Set, Set) - -Method in class org.owasp.esapi.reference.DefaultValidator -
  -
isValidInput(String, String, String, int, boolean) - -Method in interface org.owasp.esapi.Validator -
Returns true if input is valid according to the specified type. -
isValidInput(String, String, String, int, boolean) - -Method in class org.owasp.esapi.reference.DefaultValidator -
Returns true if data received from browser is valid. -
isValidInteger(String, String, int, int, boolean) - -Method in interface org.owasp.esapi.Validator -
Returns true if input is a valid integer within the range of minValue to maxValue. -
isValidInteger(String, String, int, int, boolean) - -Method in class org.owasp.esapi.reference.DefaultValidator -
  -
isValidListItem(String, String, List) - -Method in interface org.owasp.esapi.Validator -
Returns true if input is a valid list item. -
isValidListItem(String, String, List) - -Method in class org.owasp.esapi.reference.DefaultValidator -
  -
isValidNumber(String, String, long, long, boolean) - -Method in interface org.owasp.esapi.Validator -
Returns true if input is a valid number within the range of minValue to maxValue. -
isValidNumber(String, String, long, long, boolean) - -Method in class org.owasp.esapi.reference.DefaultValidator -
  -
isValidPrintable(String, byte[], int, boolean) - -Method in interface org.owasp.esapi.Validator -
Returns true if input contains only valid printable ASCII characters. -
isValidPrintable(String, String, int, boolean) - -Method in interface org.owasp.esapi.Validator -
Returns true if input contains only valid printable ASCII characters (32-126). -
isValidPrintable(String, byte[], int, boolean) - -Method in class org.owasp.esapi.reference.DefaultValidator -
Checks that all bytes are valid ASCII characters (between 33 and 126 - inclusive). -
isValidPrintable(String, String, int, boolean) - -Method in class org.owasp.esapi.reference.DefaultValidator -
  -
isValidRedirectLocation(String, String, boolean) - -Method in interface org.owasp.esapi.Validator -
Returns true if input is a valid redirect location, as defined by "ESAPI.properties". -
isValidRedirectLocation(String, String, boolean) - -Method in class org.owasp.esapi.reference.DefaultValidator -
Returns true if input is a valid redirect location. -
isValidSafeHTML(String, String, int, boolean) - -Method in interface org.owasp.esapi.Validator -
Returns true if input is "safe" HTML. -
isValidSafeHTML(String, String, int, boolean) - -Method in class org.owasp.esapi.reference.DefaultValidator -
  -
isWarningEnabled() - -Method in interface org.owasp.esapi.Logger -
Allows the caller to determine if messages logged at this level - will be discarded, to avoid performing expensive processing -
iterator() - -Method in interface org.owasp.esapi.AccessReferenceMap -
Get an iterator through the direct object references. -
iterator() - -Method in class org.owasp.esapi.reference.IntegerAccessReferenceMap -
  -
iterator() - -Method in class org.owasp.esapi.reference.RandomAccessReferenceMap -
  -
-
- - - - - - - - - - - - - - - -
- -
- - - -A B C D E F G H I J K L M N O P R S T U V W
- - - diff --git a/javadoc/index.html b/javadoc/index.html deleted file mode 100644 index 7d2085a92..000000000 --- a/javadoc/index.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - -Generated Documentation (Untitled) - - - - - - - - - -<H2> -Frame Alert</H2> - -<P> -This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. -<BR> -Link to<A HREF="overview-summary.html">Non-frame version.</A> - - - diff --git a/javadoc/org/owasp/esapi/AccessControlException.html b/javadoc/org/owasp/esapi/AccessControlException.html deleted file mode 100644 index 2b6e7c6ae..000000000 --- a/javadoc/org/owasp/esapi/AccessControlException.html +++ /dev/null @@ -1,277 +0,0 @@ - - - - - - -AccessControlException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class AccessControlException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.EnterpriseSecurityException
-              extended byorg.owasp.esapi.AccessControlException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
-
public class AccessControlException
extends EnterpriseSecurityException
- -

-An AccessControlException should be thrown when a user attempts to access a - resource that they are not authorized for. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
AccessControlException(java.lang.String userMessage, - java.lang.String logMessage) - -
-          Creates a new instance of EnterpriseSecurityException.
AccessControlException(java.lang.String userMessage, - java.lang.String logMessage, - java.lang.Throwable cause) - -
-          Instantiates a new access control exception.
-  - - - - - - - - - - -
Methods inherited from class org.owasp.esapi.EnterpriseSecurityException
getLogMessage, getUserMessage
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-AccessControlException

-
-public AccessControlException(java.lang.String userMessage,
-                              java.lang.String logMessage)
-
-
Creates a new instance of EnterpriseSecurityException. -

-

-
- -

-AccessControlException

-
-public AccessControlException(java.lang.String userMessage,
-                              java.lang.String logMessage,
-                              java.lang.Throwable cause)
-
-
Instantiates a new access control exception. -

-

Parameters:
cause - the cause
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/AccessController.html b/javadoc/org/owasp/esapi/AccessController.html deleted file mode 100644 index 66efe3b83..000000000 --- a/javadoc/org/owasp/esapi/AccessController.html +++ /dev/null @@ -1,488 +0,0 @@ - - - - - - -AccessController - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Interface AccessController

-
-
All Known Implementing Classes:
FileBasedAccessController
-
-
-
-
public interface AccessController
- -

-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. - -

- try {
-     ESAPI.accessController().assertAuthorizedForFunction( BUSINESS_FUNCTION );
-     // execute BUSINESS_FUNCTION
- } catch (AccessControlException ace) {
- ... 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. - -
- <% if ( ESAPI.accessController().isAuthorizedForFunction( ADMIN_FUNCTION ) ) { %>
- <a href="/doAdminFunction">ADMIN</a>
- <% } else { %>
- <a href="/doNormalFunction">NORMAL</a>
- <% } %>
- 
-

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- voidassertAuthorizedForData(java.lang.String key) - -
-          Checks if an account is authorized to access the referenced data.
- voidassertAuthorizedForFile(java.lang.String filepath) - -
-          Checks if an account is authorized to access the referenced file.
- voidassertAuthorizedForFunction(java.lang.String functionName) - -
-          Checks if an account is authorized to access the referenced function.
- voidassertAuthorizedForService(java.lang.String serviceName) - -
-          Checks if an account is authorized to access the referenced service.
- voidassertAuthorizedForURL(java.lang.String url) - -
-          Checks if an account is authorized to access the referenced URL.
- booleanisAuthorizedForData(java.lang.String key) - -
-          Checks if an account is authorized to access the referenced data.
- booleanisAuthorizedForFile(java.lang.String filepath) - -
-          Checks if an account is authorized to access the referenced file.
- booleanisAuthorizedForFunction(java.lang.String functionName) - -
-          Checks if an account is authorized to access the referenced function.
- booleanisAuthorizedForService(java.lang.String serviceName) - -
-          Checks if an account is authorized to access the referenced service.
- booleanisAuthorizedForURL(java.lang.String url) - -
-          Checks if an account is authorized to access the referenced URL.
-  -

- - - - - - - - - - - - - - -
-Method Detail
- -

-isAuthorizedForURL

-
-public boolean isAuthorizedForURL(java.lang.String url)
-
-
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: -
ESAPI.accessController().isAuthorizedForURL(request.getRequestURI().toString());
-

-

- -
Returns:
true, if is authorized for URL
-
-
-
- -

-isAuthorizedForFunction

-
-public boolean isAuthorizedForFunction(java.lang.String functionName)
-
-
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. -

-

-
Parameters:
functionName - the function name -
Returns:
true, if is authorized for function
-
-
-
- -

-isAuthorizedForData

-
-public boolean isAuthorizedForData(java.lang.String key)
-
-
Checks if an account is authorized to access the referenced data. The implementation should define the data - "namespace" to be enforced. -

-

-
Parameters:
key - the key -
Returns:
true, if is authorized for data
-
-
-
- -

-isAuthorizedForFile

-
-public boolean isAuthorizedForFile(java.lang.String filepath)
-
-
Checks if an account is authorized to access the referenced file. The implementation should be extremely careful - about canonicalization. -

-

-
Parameters:
filepath - the path of the file to be checked, including filename -
Returns:
true, if is authorized for file
See Also:
Encoder.canonicalize(String)
-
-
-
- -

-isAuthorizedForService

-
-public boolean isAuthorizedForService(java.lang.String serviceName)
-
-
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. -

-

-
Parameters:
serviceName - the service name -
Returns:
true, if is authorized for service
-
-
-
- -

-assertAuthorizedForURL

-
-public void assertAuthorizedForURL(java.lang.String url)
-                            throws AccessControlException
-
-
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: -
ESAPI.accessController().assertAuthorizedForURL(request.getRequestURI().toString());
-

-

-
Parameters:
url - the url as returned by request.getRequestURI().toString() -
Throws: -
AccessControlException - if access is not permitted
-
-
-
- -

-assertAuthorizedForFunction

-
-public void assertAuthorizedForFunction(java.lang.String functionName)
-                                 throws AccessControlException
-
-
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. -

-

-
Parameters:
functionName - the function name -
Throws: -
AccessControlException - if access is not permitted
-
-
-
- -

-assertAuthorizedForData

-
-public void assertAuthorizedForData(java.lang.String key)
-                             throws AccessControlException
-
-
Checks if an account is authorized to access the referenced data. The implementation should define the data - "namespace" to be enforced. -

-

-
Parameters:
key - the key -
Throws: -
AccessControlException - is access is not permitted
-
-
-
- -

-assertAuthorizedForFile

-
-public void assertAuthorizedForFile(java.lang.String filepath)
-                             throws AccessControlException
-
-
Checks if an account is authorized to access the referenced file. The implementation should be extremely careful - about canonicalization. -

-

-
Parameters:
filepath - the path of the file to be checked, including filename -
Throws: -
AccessControlException - is access is not permitted
See Also:
Encoder.canonicalize(String)
-
-
-
- -

-assertAuthorizedForService

-
-public void assertAuthorizedForService(java.lang.String serviceName)
-                                throws AccessControlException
-
-
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. -

-

-
Parameters:
serviceName - the service name -
Throws: -
AccessControlException
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/AccessControllerTest.html b/javadoc/org/owasp/esapi/AccessControllerTest.html deleted file mode 100644 index ffa35d691..000000000 --- a/javadoc/org/owasp/esapi/AccessControllerTest.html +++ /dev/null @@ -1,426 +0,0 @@ - - - - - - -AccessControllerTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class AccessControllerTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.AccessControllerTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class AccessControllerTest
extends junit.framework.TestCase
- -

-The Class AccessControllerTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
AccessControllerTest(java.lang.String testName) - -
-          Instantiates a new access controller test.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestIsAuthorizedForBackendService() - -
-          Test of isAuthorizedForBackendService method, of class - org.owasp.esapi.AccessController.
- voidtestIsAuthorizedForData() - -
-          Test of isAuthorizedForData method, of class - org.owasp.esapi.AccessController.
- voidtestIsAuthorizedForFile() - -
-          Test of isAuthorizedForFile method, of class - org.owasp.esapi.AccessController.
- voidtestIsAuthorizedForFunction() - -
-          Test of isAuthorizedForFunction method, of class - org.owasp.esapi.AccessController.
- voidtestIsAuthorizedForURL() - -
-          Test of isAuthorizedForURL method, of class - org.owasp.esapi.AccessController.
- voidtestMatchRule() - -
-           
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-AccessControllerTest

-
-public AccessControllerTest(java.lang.String testName)
-                     throws java.lang.Exception
-
-
Instantiates a new access controller test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testMatchRule

-
-public void testMatchRule()
-
-
-
-
-
-
- -

-testIsAuthorizedForURL

-
-public void testIsAuthorizedForURL()
-                            throws java.lang.Exception
-
-
Test of isAuthorizedForURL method, of class - org.owasp.esapi.AccessController. -

-

- -
Throws: -
java.lang.Exception
-
-
-
- -

-testIsAuthorizedForFunction

-
-public void testIsAuthorizedForFunction()
-
-
Test of isAuthorizedForFunction method, of class - org.owasp.esapi.AccessController. -

-

-
-
-
-
- -

-testIsAuthorizedForData

-
-public void testIsAuthorizedForData()
-
-
Test of isAuthorizedForData method, of class - org.owasp.esapi.AccessController. -

-

-
-
-
-
- -

-testIsAuthorizedForFile

-
-public void testIsAuthorizedForFile()
-
-
Test of isAuthorizedForFile method, of class - org.owasp.esapi.AccessController. -

-

-
-
-
-
- -

-testIsAuthorizedForBackendService

-
-public void testIsAuthorizedForBackendService()
-
-
Test of isAuthorizedForBackendService method, of class - org.owasp.esapi.AccessController. -

-

-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/AccessReferenceMap.html b/javadoc/org/owasp/esapi/AccessReferenceMap.html deleted file mode 100644 index 72acc2120..000000000 --- a/javadoc/org/owasp/esapi/AccessReferenceMap.html +++ /dev/null @@ -1,389 +0,0 @@ - - - - - - -AccessReferenceMap - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Interface AccessReferenceMap

-
-
All Known Implementing Classes:
IntegerAccessReferenceMap, RandomAccessReferenceMap
-
-
-
-
public interface 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. 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.StringaddDirectReference(java.lang.Object direct) - -
-          Adds a direct reference to the AccessReferenceMap and generates an associated indirect reference.
- java.lang.ObjectgetDirectReference(java.lang.String indirectReference) - -
-          Get the original direct object reference from an indirect reference.
- java.lang.StringgetIndirectReference(java.lang.Object directReference) - -
-          Get a safe indirect reference to use in place of a potentially sensitive - direct object reference.
- java.util.Iteratoriterator() - -
-          Get an iterator through the direct object references.
- java.lang.StringremoveDirectReference(java.lang.Object direct) - -
-          Removes a direct reference and its associated indirect reference from the AccessReferenceMap.
- voidupdate(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. -

-

- -
Returns:
the iterator
-
-
-
- -

-getIndirectReference

-
-public java.lang.String getIndirectReference(java.lang.Object directReference)
-
-
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. -

-

-
Parameters:
directReference - the direct reference -
Returns:
the indirect reference
-
-
-
- -

-getDirectReference

-
-public java.lang.Object getDirectReference(java.lang.String indirectReference)
-                                    throws AccessControlException
-
-
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
-
-
-
- -

-addDirectReference

-
-public java.lang.String addDirectReference(java.lang.Object direct)
-
-
Adds a direct reference to the AccessReferenceMap and generates an associated indirect reference. -

-

-
Parameters:
direct - the direct reference -
Returns:
the corresponding indirect reference
-
-
-
- -

-removeDirectReference

-
-public java.lang.String removeDirectReference(java.lang.Object direct)
-                                       throws AccessControlException
-
-
Removes a direct reference and its associated indirect reference from the AccessReferenceMap. -

-

-
Parameters:
direct - the direct reference to remove -
Returns:
the corresponding indirect reference -
Throws: -
AccessControlException
-
-
-
- -

-update

-
-public 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. -

-

-
Parameters:
directReferences -
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/AccessReferenceMapTest.html b/javadoc/org/owasp/esapi/AccessReferenceMapTest.html deleted file mode 100644 index 721b414e5..000000000 --- a/javadoc/org/owasp/esapi/AccessReferenceMapTest.html +++ /dev/null @@ -1,428 +0,0 @@ - - - - - - -AccessReferenceMapTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class AccessReferenceMapTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.AccessReferenceMapTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class AccessReferenceMapTest
extends junit.framework.TestCase
- -

-The Class AccessReferenceMapTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
AccessReferenceMapTest(java.lang.String testName) - -
-          Instantiates a new access reference map test.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestAddDirectReference() - -
-           
- voidtestGetDirectReference() - -
-          Test of getDirectReference method, of class - org.owasp.esapi.AccessReferenceMap.
- voidtestGetIndirectReference() - -
-          Test of getIndirectReference method, of class - org.owasp.esapi.AccessReferenceMap.
- voidtestIterator() - -
-          Test of iterator method, of class org.owasp.esapi.AccessReferenceMap.
- voidtestRemoveDirectReference() - -
-           
- voidtestUpdate() - -
-          Test of update method, of class org.owasp.esapi.AccessReferenceMap.
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-AccessReferenceMapTest

-
-public AccessReferenceMapTest(java.lang.String testName)
-
-
Instantiates a new access reference map test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testUpdate

-
-public void testUpdate()
-                throws AuthenticationException,
-                       EncryptionException
-
-
Test of update method, of class org.owasp.esapi.AccessReferenceMap. -

-

- -
Throws: -
AuthenticationException - the authentication exception -
EncryptionException
-
-
-
- -

-testIterator

-
-public void testIterator()
-
-
Test of iterator method, of class org.owasp.esapi.AccessReferenceMap. -

-

-
-
-
-
- -

-testGetIndirectReference

-
-public void testGetIndirectReference()
-
-
Test of getIndirectReference method, of class - org.owasp.esapi.AccessReferenceMap. -

-

-
-
-
-
- -

-testGetDirectReference

-
-public void testGetDirectReference()
-                            throws AccessControlException
-
-
Test of getDirectReference method, of class - org.owasp.esapi.AccessReferenceMap. -

-

- -
Throws: -
AccessControlException - the access control exception
-
-
-
- -

-testAddDirectReference

-
-public void testAddDirectReference()
-                            throws AccessControlException
-
-
- -
Throws: -
AccessControlException
-
-
-
- -

-testRemoveDirectReference

-
-public void testRemoveDirectReference()
-                               throws AccessControlException
-
-
- -
Throws: -
AccessControlException
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/AllTests.html b/javadoc/org/owasp/esapi/AllTests.html deleted file mode 100644 index bc761c0b0..000000000 --- a/javadoc/org/owasp/esapi/AllTests.html +++ /dev/null @@ -1,288 +0,0 @@ - - - - - - -AllTests - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class AllTests

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.AllTests
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class AllTests
extends junit.framework.TestCase
- -

-The Class AllTests. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
AllTests(java.lang.String testName) - -
-          Instantiates a new all tests.
-  - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          suite method automatically generated by JUnit module.
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-AllTests

-
-public AllTests(java.lang.String testName)
-
-
Instantiates a new all tests. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
suite method automatically generated by JUnit module. -

-

- -
Returns:
the test
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/AuthenticationAccountsException.html b/javadoc/org/owasp/esapi/AuthenticationAccountsException.html deleted file mode 100644 index ffd28a786..000000000 --- a/javadoc/org/owasp/esapi/AuthenticationAccountsException.html +++ /dev/null @@ -1,279 +0,0 @@ - - - - - - -AuthenticationAccountsException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class AuthenticationAccountsException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.EnterpriseSecurityException
-              extended byorg.owasp.esapi.AuthenticationException
-                  extended byorg.owasp.esapi.AuthenticationAccountsException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
-
public class AuthenticationAccountsException
extends AuthenticationException
- -

-An AuthenticationException should be thrown when anything goes wrong during - login or logout. They are also appropriate for any problems related to - identity management. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
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.
-  - - - - - - - - - - -
Methods inherited from class org.owasp.esapi.EnterpriseSecurityException
getLogMessage, getUserMessage
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-AuthenticationAccountsException

-
-public AuthenticationAccountsException(java.lang.String userMessage,
-                                       java.lang.String logMessage)
-
-
Creates a new instance of EnterpriseSecurityException. -

-

-
- -

-AuthenticationAccountsException

-
-public AuthenticationAccountsException(java.lang.String userMessage,
-                                       java.lang.String logMessage,
-                                       java.lang.Throwable cause)
-
-
Instantiates a new authentication exception. -

-

Parameters:
cause - the cause
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/AuthenticationCredentialsException.html b/javadoc/org/owasp/esapi/AuthenticationCredentialsException.html deleted file mode 100644 index f0cef0d15..000000000 --- a/javadoc/org/owasp/esapi/AuthenticationCredentialsException.html +++ /dev/null @@ -1,279 +0,0 @@ - - - - - - -AuthenticationCredentialsException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class AuthenticationCredentialsException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.EnterpriseSecurityException
-              extended byorg.owasp.esapi.AuthenticationException
-                  extended byorg.owasp.esapi.AuthenticationCredentialsException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
-
public class AuthenticationCredentialsException
extends AuthenticationException
- -

-An AuthenticationException should be thrown when anything goes wrong during - login or logout. They are also appropriate for any problems related to - identity management. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
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.
-  - - - - - - - - - - -
Methods inherited from class org.owasp.esapi.EnterpriseSecurityException
getLogMessage, getUserMessage
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-AuthenticationCredentialsException

-
-public AuthenticationCredentialsException(java.lang.String userMessage,
-                                          java.lang.String logMessage)
-
-
Creates a new instance of EnterpriseSecurityException. -

-

-
- -

-AuthenticationCredentialsException

-
-public AuthenticationCredentialsException(java.lang.String userMessage,
-                                          java.lang.String logMessage,
-                                          java.lang.Throwable cause)
-
-
Instantiates a new authentication exception. -

-

Parameters:
cause - the cause
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/AuthenticationException.html b/javadoc/org/owasp/esapi/AuthenticationException.html deleted file mode 100644 index 0cd9eea09..000000000 --- a/javadoc/org/owasp/esapi/AuthenticationException.html +++ /dev/null @@ -1,281 +0,0 @@ - - - - - - -AuthenticationException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class AuthenticationException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.EnterpriseSecurityException
-              extended byorg.owasp.esapi.AuthenticationException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
Direct Known Subclasses:
AuthenticationAccountsException, AuthenticationCredentialsException, AuthenticationHostException, AuthenticationLoginException
-
-
-
-
public class AuthenticationException
extends EnterpriseSecurityException
- -

-An AuthenticationException should be thrown when anything goes wrong during - login or logout. They are also appropriate for any problems related to - identity management. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
AuthenticationException(java.lang.String userMessage, - java.lang.String logMessage) - -
-          Creates a new instance of EnterpriseSecurityException.
AuthenticationException(java.lang.String userMessage, - java.lang.String logMessage, - java.lang.Throwable cause) - -
-          Instantiates a new authentication exception.
-  - - - - - - - - - - -
Methods inherited from class org.owasp.esapi.EnterpriseSecurityException
getLogMessage, getUserMessage
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-AuthenticationException

-
-public AuthenticationException(java.lang.String userMessage,
-                               java.lang.String logMessage)
-
-
Creates a new instance of EnterpriseSecurityException. -

-

-
- -

-AuthenticationException

-
-public AuthenticationException(java.lang.String userMessage,
-                               java.lang.String logMessage,
-                               java.lang.Throwable cause)
-
-
Instantiates a new authentication exception. -

-

Parameters:
cause - the cause
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/AuthenticationHostException.html b/javadoc/org/owasp/esapi/AuthenticationHostException.html deleted file mode 100644 index 4526e02f6..000000000 --- a/javadoc/org/owasp/esapi/AuthenticationHostException.html +++ /dev/null @@ -1,278 +0,0 @@ - - - - - - -AuthenticationHostException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class AuthenticationHostException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.EnterpriseSecurityException
-              extended byorg.owasp.esapi.AuthenticationException
-                  extended byorg.owasp.esapi.AuthenticationHostException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
-
public class AuthenticationHostException
extends AuthenticationException
- -

-An AuthenticationHostException should be thrown when there is a problem with - the host involved with authentication, particularly if the host changes unexpectedly. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
AuthenticationHostException(java.lang.String userMessage, - java.lang.String logMessage) - -
-          Creates a new instance of AuthenticationHostException.
AuthenticationHostException(java.lang.String userMessage, - java.lang.String logMessage, - java.lang.Throwable cause) - -
-          Instantiates a new authentication exception.
-  - - - - - - - - - - -
Methods inherited from class org.owasp.esapi.EnterpriseSecurityException
getLogMessage, getUserMessage
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-AuthenticationHostException

-
-public AuthenticationHostException(java.lang.String userMessage,
-                                   java.lang.String logMessage)
-
-
Creates a new instance of AuthenticationHostException. -

-

-
- -

-AuthenticationHostException

-
-public AuthenticationHostException(java.lang.String userMessage,
-                                   java.lang.String logMessage,
-                                   java.lang.Throwable cause)
-
-
Instantiates a new authentication exception. -

-

Parameters:
cause - the cause
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/AuthenticationLoginException.html b/javadoc/org/owasp/esapi/AuthenticationLoginException.html deleted file mode 100644 index 981e58a1b..000000000 --- a/javadoc/org/owasp/esapi/AuthenticationLoginException.html +++ /dev/null @@ -1,279 +0,0 @@ - - - - - - -AuthenticationLoginException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class AuthenticationLoginException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.EnterpriseSecurityException
-              extended byorg.owasp.esapi.AuthenticationException
-                  extended byorg.owasp.esapi.AuthenticationLoginException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
-
public class AuthenticationLoginException
extends AuthenticationException
- -

-An AuthenticationException should be thrown when anything goes wrong during - login or logout. They are also appropriate for any problems related to - identity management. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
AuthenticationLoginException(java.lang.String userMessage, - java.lang.String logMessage) - -
-          Creates a new instance of EnterpriseSecurityException.
AuthenticationLoginException(java.lang.String userMessage, - java.lang.String logMessage, - java.lang.Throwable cause) - -
-          Instantiates a new authentication exception.
-  - - - - - - - - - - -
Methods inherited from class org.owasp.esapi.EnterpriseSecurityException
getLogMessage, getUserMessage
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-AuthenticationLoginException

-
-public AuthenticationLoginException(java.lang.String userMessage,
-                                    java.lang.String logMessage)
-
-
Creates a new instance of EnterpriseSecurityException. -

-

-
- -

-AuthenticationLoginException

-
-public AuthenticationLoginException(java.lang.String userMessage,
-                                    java.lang.String logMessage,
-                                    java.lang.Throwable cause)
-
-
Instantiates a new authentication exception. -

-

Parameters:
cause - the cause
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/Authenticator.html b/javadoc/org/owasp/esapi/Authenticator.html deleted file mode 100644 index 6c9b948e2..000000000 --- a/javadoc/org/owasp/esapi/Authenticator.html +++ /dev/null @@ -1,694 +0,0 @@ - - - - - - -Authenticator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Interface Authenticator

-
-
All Known Implementing Classes:
FileBasedAuthenticator
-
-
-
-
public interface Authenticator
- -

-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
- voidchangePassword(User user, - java.lang.String currentPassword, - java.lang.String newPassword, - java.lang.String newPassword2) - -
-          Changes the password for the specified user.
- voidclearCurrent() - -
-          Clear the current user.
- UsercreateUser(java.lang.String accountName, - java.lang.String password1, - java.lang.String password2) - -
-          Creates a new User with the information provided.
- booleanexists(java.lang.String accountName) - -
-          Determine if the account exists.
- java.lang.StringgenerateStrongPassword() - -
-          Generate a strong password.
- java.lang.StringgenerateStrongPassword(User user, - java.lang.String oldPassword) - -
-          Generate strong password that takes into account the user's information and old password.
- UsergetCurrentUser() - -
-          Returns the currently logged in User.
- UsergetUser(long accountId) - -
-          Returns the User matching the provided accountId.
- UsergetUser(java.lang.String accountName) - -
-          Returns the User matching the provided accountName.
- java.util.SetgetUserNames() - -
-          Gets a collection containing all the existing user names.
- java.lang.StringhashPassword(java.lang.String password, - java.lang.String accountName) - -
-          Returns a string representation of the hashed password, using the - accountName as the salt.
- Userlogin(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.
- voidlogout() - -
-          Logs out the current user.
- voidremoveUser(java.lang.String accountName) - -
-          Removes the account.
- voidsetCurrentUser(User user) - -
-          Sets the currently logged in User.
- voidverifyAccountNameStrength(java.lang.String accountName) - -
-          Ensures that the account name passes site-specific complexity requirements, like minimum length.
- booleanverifyPassword(User user, - java.lang.String password) - -
-          Verify that the supplied password matches the password for this user.
- voidverifyPasswordStrength(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. -

-

-
-
-
-
- -

-login

-
-public User login(javax.servlet.http.HttpServletRequest request,
-                  javax.servlet.http.HttpServletResponse response)
-           throws AuthenticationException
-
-
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
-
-
-
- -

-verifyPassword

-
-public boolean verifyPassword(User user,
-                              java.lang.String password)
-
-
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
-
-
-
- -

-logout

-
-public void logout()
-
-
Logs out the current user. -

-

-
-
-
-
- -

-createUser

-
-public User createUser(java.lang.String accountName,
-                       java.lang.String password1,
-                       java.lang.String password2)
-                throws AuthenticationException
-
-
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. -
Returns:
the User that has been created -
Throws: -
AuthenticationException - if user creation fails
-
-
-
- -

-generateStrongPassword

-
-public java.lang.String generateStrongPassword()
-
-
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. -

-

- -
Returns:
a password with strong password strength
-
-
-
- -

-generateStrongPassword

-
-public java.lang.String generateStrongPassword(User user,
-                                               java.lang.String oldPassword)
-
-
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. -
Returns:
a password with strong password strength
-
-
-
- -

-changePassword

-
-public void changePassword(User user,
-                           java.lang.String currentPassword,
-                           java.lang.String newPassword,
-                           java.lang.String newPassword2)
-                    throws AuthenticationException
-
-
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 -
Throws: -
AuthenticationException - if any errors occur
-
-
-
- -

-getUser

-
-public User getUser(long accountId)
-
-
Returns the User matching the provided accountId. -

-

-
Parameters:
accountId - the account id -
Returns:
the matching User object, or null if no match exists
-
-
-
- -

-getUser

-
-public User getUser(java.lang.String accountName)
-
-
Returns the User matching the provided accountName. -

-

-
Parameters:
accountName - the account name -
Returns:
the matching User object, or null if no match exists
-
-
-
- -

-getUserNames

-
-public java.util.Set getUserNames()
-
-
Gets a collection containing all the existing user names. -

-

- -
Returns:
a set of all user names
-
-
-
- -

-getCurrentUser

-
-public User getCurrentUser()
-
-
Returns the currently logged in User. -

-

- -
Returns:
the matching User object, or the Anonymous user if no match - exists
-
-
-
- -

-setCurrentUser

-
-public void setCurrentUser(User user)
-
-
Sets the currently logged in User. -

-

-
Parameters:
user - the user to set as the current user
-
-
-
- -

-hashPassword

-
-public java.lang.String hashPassword(java.lang.String password,
-                                     java.lang.String accountName)
-                              throws EncryptionException
-
-
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 -
Returns:
the hashed password -
Throws: -
EncryptionException
-
-
-
- -

-removeUser

-
-public void removeUser(java.lang.String accountName)
-                throws AuthenticationException
-
-
Removes the account. -

-

-
Parameters:
accountName - the account name to remove -
Throws: -
AuthenticationException - the authentication exception if user does not exist
-
-
-
- -

-verifyAccountNameStrength

-
-public void verifyAccountNameStrength(java.lang.String accountName)
-                               throws AuthenticationException
-
-
Ensures that the account name passes site-specific complexity requirements, like minimum length. -

-

-
Parameters:
accountName - the account name -
Throws: -
AuthenticationException - if account name does not meet complexity requirements
-
-
-
- -

-verifyPasswordStrength

-
-public void verifyPasswordStrength(java.lang.String oldPassword,
-                                   java.lang.String newPassword)
-                            throws AuthenticationException
-
-
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
-
-
-
- -

-exists

-
-public boolean exists(java.lang.String accountName)
-
-
Determine if the account exists. -

-

-
Parameters:
accountName - the account name -
Returns:
true, if the account exists
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/AuthenticatorTest.html b/javadoc/org/owasp/esapi/AuthenticatorTest.html deleted file mode 100644 index 3c4350950..000000000 --- a/javadoc/org/owasp/esapi/AuthenticatorTest.html +++ /dev/null @@ -1,656 +0,0 @@ - - - - - - -AuthenticatorTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class AuthenticatorTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.AuthenticatorTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class AuthenticatorTest
extends junit.framework.TestCase
- -

-The Class AuthenticatorTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
AuthenticatorTest(java.lang.String testName) - -
-          Instantiates a new authenticator test.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestCreateUser() - -
-          Test of createAccount method, of class org.owasp.esapi.Authenticator.
- voidtestExists() - -
-          Test of exists method, of class org.owasp.esapi.Authenticator.
- voidtestGenerateStrongPassword() - -
-          Test of generateStrongPassword method, of class - org.owasp.esapi.Authenticator.
- voidtestGetCurrentUser() - -
-          Test of getCurrentUser method, of class org.owasp.esapi.Authenticator.
- voidtestGetUser() - -
-          Test of getUser method, of class org.owasp.esapi.Authenticator.
- voidtestGetUserFromSession() - -
-          Test get user from session.
- voidtestGetUserNames() - -
-          Test get user names.
- voidtestHashPassword() - -
-          Test of hashPassword method, of class org.owasp.esapi.Authenticator.
- voidtestLogin() - -
-          Test of login method, of class org.owasp.esapi.Authenticator.
- voidtestMain() - -
-          Test of main method, of class org.owasp.esapi.Authenticator.
- voidtestRemoveUser() - -
-          Test of removeAccount method, of class org.owasp.esapi.Authenticator.
- voidtestSaveUsers() - -
-          Test of saveUsers method, of class org.owasp.esapi.Authenticator.
- voidtestSetCurrentUser() - -
-          Test of setCurrentUser method, of class org.owasp.esapi.Authenticator.
- voidtestSetCurrentUserWithRequest() - -
-          Test of setCurrentUser method, of class org.owasp.esapi.Authenticator.
- voidtestValidatePasswordStrength() - -
-          Test of validatePasswordStrength method, of class - org.owasp.esapi.Authenticator.
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-AuthenticatorTest

-
-public AuthenticatorTest(java.lang.String testName)
-
-
Instantiates a new authenticator test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testCreateUser

-
-public void testCreateUser()
-                    throws AuthenticationException,
-                           EncryptionException
-
-
Test of createAccount method, of class org.owasp.esapi.Authenticator. -

-

- -
Throws: -
AuthenticationException - the authentication exception -
EncryptionException
-
-
-
- -

-testGenerateStrongPassword

-
-public void testGenerateStrongPassword()
-                                throws AuthenticationException
-
-
Test of generateStrongPassword method, of class - org.owasp.esapi.Authenticator. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testGetCurrentUser

-
-public void testGetCurrentUser()
-                        throws java.lang.Exception
-
-
Test of getCurrentUser method, of class org.owasp.esapi.Authenticator. -

-

- -
Throws: -
java.lang.InterruptedException - * -
AuthenticationException - the authentication exception -
java.lang.Exception
-
-
-
- -

-testGetUser

-
-public void testGetUser()
-                 throws AuthenticationException
-
-
Test of getUser method, of class org.owasp.esapi.Authenticator. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testGetUserFromSession

-
-public void testGetUserFromSession()
-                            throws AuthenticationException
-
-
Test get user from session. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testGetUserNames

-
-public void testGetUserNames()
-                      throws AuthenticationException
-
-
Test get user names. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testHashPassword

-
-public void testHashPassword()
-                      throws EncryptionException
-
-
Test of hashPassword method, of class org.owasp.esapi.Authenticator. -

-

- -
Throws: -
EncryptionException
-
-
-
- -

-testLogin

-
-public void testLogin()
-               throws AuthenticationException
-
-
Test of login method, of class org.owasp.esapi.Authenticator. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testRemoveUser

-
-public void testRemoveUser()
-                    throws java.lang.Exception
-
-
Test of removeAccount method, of class org.owasp.esapi.Authenticator. -

-

- -
Throws: -
java.lang.Exception - the exception
-
-
-
- -

-testSaveUsers

-
-public void testSaveUsers()
-                   throws java.lang.Exception
-
-
Test of saveUsers method, of class org.owasp.esapi.Authenticator. -

-

- -
Throws: -
java.lang.Exception - the exception
-
-
-
- -

-testSetCurrentUser

-
-public void testSetCurrentUser()
-                        throws AuthenticationException
-
-
Test of setCurrentUser method, of class org.owasp.esapi.Authenticator. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testSetCurrentUserWithRequest

-
-public void testSetCurrentUserWithRequest()
-                                   throws AuthenticationException
-
-
Test of setCurrentUser method, of class org.owasp.esapi.Authenticator. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testValidatePasswordStrength

-
-public void testValidatePasswordStrength()
-                                  throws AuthenticationException
-
-
Test of validatePasswordStrength method, of class - org.owasp.esapi.Authenticator. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testExists

-
-public void testExists()
-                throws java.lang.Exception
-
-
Test of exists method, of class org.owasp.esapi.Authenticator. -

-

- -
Throws: -
java.lang.Exception - the exception
-
-
-
- -

-testMain

-
-public void testMain()
-              throws java.lang.Exception
-
-
Test of main method, of class org.owasp.esapi.Authenticator. -

-

- -
Throws: -
java.lang.Exception
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/AvailabilityException.html b/javadoc/org/owasp/esapi/AvailabilityException.html deleted file mode 100644 index 4a50179ec..000000000 --- a/javadoc/org/owasp/esapi/AvailabilityException.html +++ /dev/null @@ -1,278 +0,0 @@ - - - - - - -AvailabilityException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class AvailabilityException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.EnterpriseSecurityException
-              extended byorg.owasp.esapi.AvailabilityException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
-
public class AvailabilityException
extends EnterpriseSecurityException
- -

-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. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
AvailabilityException(java.lang.String userMessage, - java.lang.String logMessage) - -
-          Creates a new instance of AvailabilityException.
AvailabilityException(java.lang.String userMessage, - java.lang.String logMessage, - java.lang.Throwable cause) - -
-          Instantiates a new AvailabilityException.
-  - - - - - - - - - - -
Methods inherited from class org.owasp.esapi.EnterpriseSecurityException
getLogMessage, getUserMessage
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-AvailabilityException

-
-public AvailabilityException(java.lang.String userMessage,
-                             java.lang.String logMessage)
-
-
Creates a new instance of AvailabilityException. -

-

-
- -

-AvailabilityException

-
-public AvailabilityException(java.lang.String userMessage,
-                             java.lang.String logMessage,
-                             java.lang.Throwable cause)
-
-
Instantiates a new AvailabilityException. -

-

Parameters:
cause - the cause
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/CertificateException.html b/javadoc/org/owasp/esapi/CertificateException.html deleted file mode 100644 index 4aeeff768..000000000 --- a/javadoc/org/owasp/esapi/CertificateException.html +++ /dev/null @@ -1,277 +0,0 @@ - - - - - - -CertificateException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class CertificateException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.EnterpriseSecurityException
-              extended byorg.owasp.esapi.CertificateException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
-
public class CertificateException
extends EnterpriseSecurityException
- -

-A CertificateException should be thrown for any problems that arise during - processing of digital certificates. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
CertificateException(java.lang.String userMessage, - java.lang.String logMessage) - -
-          Creates a new instance of CertificateException.
CertificateException(java.lang.String userMessage, - java.lang.String logMessage, - java.lang.Throwable cause) - -
-          Instantiates a new CertificateException.
-  - - - - - - - - - - -
Methods inherited from class org.owasp.esapi.EnterpriseSecurityException
getLogMessage, getUserMessage
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-CertificateException

-
-public CertificateException(java.lang.String userMessage,
-                            java.lang.String logMessage)
-
-
Creates a new instance of CertificateException. -

-

-
- -

-CertificateException

-
-public CertificateException(java.lang.String userMessage,
-                            java.lang.String logMessage,
-                            java.lang.Throwable cause)
-
-
Instantiates a new CertificateException. -

-

Parameters:
cause - the cause
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/ESAPI.html b/javadoc/org/owasp/esapi/ESAPI.html deleted file mode 100644 index 285084bfa..000000000 --- a/javadoc/org/owasp/esapi/ESAPI.html +++ /dev/null @@ -1,716 +0,0 @@ - - - - - - -ESAPI - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class ESAPI

-
-java.lang.Object
-  extended byorg.owasp.esapi.ESAPI
-
-
-
-
public class ESAPI
extends java.lang.Object
- -

-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. -

- -

-


- -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
-static AccessControlleraccessController() - -
-           
-static Authenticatorauthenticator() - -
-           
-static javax.servlet.http.HttpServletRequestcurrentRequest() - -
-           
-static javax.servlet.http.HttpServletResponsecurrentResponse() - -
-           
-static Encoderencoder() - -
-           
-static Encryptorencryptor() - -
-           
-static Executorexecutor() - -
-           
-static LoggergetLogger(java.lang.Class clazz) - -
-           
-static LoggergetLogger(java.lang.String name) - -
-           
-static HTTPUtilitieshttpUtilities() - -
-           
-static IntrusionDetectorintrusionDetector() - -
-           
-static Loggerlog() - -
-           
-static Randomizerrandomizer() - -
-           
-static SecurityConfigurationsecurityConfiguration() - -
-           
-static voidsetAccessController(AccessController accessController) - -
-           
-static voidsetAuthenticator(Authenticator authenticator) - -
-           
-static voidsetEncoder(Encoder encoder) - -
-           
-static voidsetEncryptor(Encryptor encryptor) - -
-           
-static voidsetExecutor(Executor executor) - -
-           
-static voidsetHttpUtilities(HTTPUtilities httpUtilities) - -
-           
-static voidsetIntrusionDetector(IntrusionDetector intrusionDetector) - -
-           
-static voidsetLogFactory(LogFactory factory) - -
-           
-static voidsetRandomizer(Randomizer randomizer) - -
-           
-static voidsetSecurityConfiguration(SecurityConfiguration securityConfiguration) - -
-           
-static voidsetValidator(Validator validator) - -
-           
-static Validatorvalidator() - -
-           
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - - - - -
-Method Detail
- -

-currentRequest

-
-public static javax.servlet.http.HttpServletRequest currentRequest()
-
-
-
-
-
-
- -

-currentResponse

-
-public static javax.servlet.http.HttpServletResponse currentResponse()
-
-
-
-
-
-
- -

-accessController

-
-public static AccessController accessController()
-
-
- -
Returns:
the accessController
-
-
-
- -

-setAccessController

-
-public static void setAccessController(AccessController accessController)
-
-
-
Parameters:
accessController - the accessController to set
-
-
-
- -

-authenticator

-
-public static Authenticator authenticator()
-
-
- -
Returns:
the authenticator
-
-
-
- -

-setAuthenticator

-
-public static void setAuthenticator(Authenticator authenticator)
-
-
-
Parameters:
authenticator - the authenticator to set
-
-
-
- -

-encoder

-
-public static Encoder encoder()
-
-
- -
Returns:
the encoder
-
-
-
- -

-setEncoder

-
-public static void setEncoder(Encoder encoder)
-
-
-
Parameters:
encoder - the encoder to set
-
-
-
- -

-encryptor

-
-public static Encryptor encryptor()
-
-
- -
Returns:
the encryptor
-
-
-
- -

-setEncryptor

-
-public static void setEncryptor(Encryptor encryptor)
-
-
-
Parameters:
encryptor - the encryptor to set
-
-
-
- -

-executor

-
-public static Executor executor()
-
-
- -
Returns:
the executor
-
-
-
- -

-setExecutor

-
-public static void setExecutor(Executor executor)
-
-
-
Parameters:
executor - the executor to set
-
-
-
- -

-httpUtilities

-
-public static HTTPUtilities httpUtilities()
-
-
- -
Returns:
the httpUtilities
-
-
-
- -

-setHttpUtilities

-
-public static void setHttpUtilities(HTTPUtilities httpUtilities)
-
-
-
Parameters:
httpUtilities - the httpUtilities to set
-
-
-
- -

-intrusionDetector

-
-public static IntrusionDetector intrusionDetector()
-
-
- -
Returns:
the intrusionDetector
-
-
-
- -

-setIntrusionDetector

-
-public static void setIntrusionDetector(IntrusionDetector intrusionDetector)
-
-
-
Parameters:
intrusionDetector - the intrusionDetector to set
-
-
-
- -

-getLogger

-
-public static Logger getLogger(java.lang.Class clazz)
-
-
-
-
-
-
- -

-getLogger

-
-public static Logger getLogger(java.lang.String name)
-
-
-
-
-
-
- -

-log

-
-public static Logger log()
-
-
-
-
-
-
- -

-setLogFactory

-
-public static void setLogFactory(LogFactory factory)
-
-
-
Parameters:
factory - the log factory to set
-
-
-
- -

-randomizer

-
-public static Randomizer randomizer()
-
-
- -
Returns:
the randomizer
-
-
-
- -

-setRandomizer

-
-public static void setRandomizer(Randomizer randomizer)
-
-
-
Parameters:
randomizer - the randomizer to set
-
-
-
- -

-securityConfiguration

-
-public static SecurityConfiguration securityConfiguration()
-
-
- -
Returns:
the securityConfiguration
-
-
-
- -

-setSecurityConfiguration

-
-public static void setSecurityConfiguration(SecurityConfiguration securityConfiguration)
-
-
-
Parameters:
securityConfiguration - the securityConfiguration to set
-
-
-
- -

-validator

-
-public static Validator validator()
-
-
- -
Returns:
the validator
-
-
-
- -

-setValidator

-
-public static void setValidator(Validator validator)
-
-
-
Parameters:
validator - the validator to set
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/ESAPITest.html b/javadoc/org/owasp/esapi/ESAPITest.html deleted file mode 100644 index 64f5cdb3c..000000000 --- a/javadoc/org/owasp/esapi/ESAPITest.html +++ /dev/null @@ -1,312 +0,0 @@ - - - - - - -ESAPITest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class ESAPITest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.ESAPITest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class ESAPITest
extends junit.framework.TestCase
- -

-The Class ExecutorTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
ESAPITest(java.lang.String testName) - -
-          Instantiates a new executor test.
-  - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestSetters() - -
-          Test of all the ESAPI setter methods
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-ESAPITest

-
-public ESAPITest(java.lang.String testName)
-
-
Instantiates a new executor test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testSetters

-
-public void testSetters()
-                 throws java.lang.Exception
-
-
Test of all the ESAPI setter methods -

-

- -
Throws: -
java.lang.Exception - the exception
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/Encoder.html b/javadoc/org/owasp/esapi/Encoder.html deleted file mode 100644 index 30529aa9a..000000000 --- a/javadoc/org/owasp/esapi/Encoder.html +++ /dev/null @@ -1,917 +0,0 @@ - - - - - - -Encoder - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Interface Encoder

-
-
All Known Implementing Classes:
DefaultEncoder
-
-
-
-
public interface Encoder
- -

-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
-
-
- -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Field Summary
-static char[]CHAR_ALPHANUMERICS - -
-           
-static char[]CHAR_DIGITS - -
-           
-static char[]CHAR_LETTERS - -
-           
-static char[]CHAR_LOWERS - -
-          Standard character sets
-static char[]CHAR_PASSWORD_DIGITS - -
-           
-static char[]CHAR_PASSWORD_LETTERS - -
-           
-static 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...)
-static char[]CHAR_PASSWORD_SPECIALS - -
-           
-static char[]CHAR_PASSWORD_UPPERS - -
-           
-static char[]CHAR_SPECIALS - -
-           
-static char[]CHAR_UPPERS - -
-           
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- java.lang.Stringcanonicalize(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.Stringcanonicalize(java.lang.String input, - boolean strict) - -
-           
- byte[]decodeFromBase64(java.lang.String input) - -
-          Decode data encoded with BASE-64 encoding.
- java.lang.StringdecodeFromURL(java.lang.String input) - -
-          Decode from URL.
- java.lang.StringencodeForBase64(byte[] input, - boolean wrap) - -
-          Encode for Base64.
- java.lang.StringencodeForCSS(java.lang.String input) - -
-          Encode data for use in Cascading Style Sheets (CSS) content.
- java.lang.StringencodeForDN(java.lang.String input) - -
-          Encode data for use in an LDAP distinguished name.
- java.lang.StringencodeForHTML(java.lang.String input) - -
-          Encode data for use in HTML content.
- java.lang.StringencodeForHTMLAttribute(java.lang.String input) - -
-          Encode data for use in HTML attributes.
- java.lang.StringencodeForJavaScript(java.lang.String input) - -
-          Encode data for insertion inside a data value in JavaScript.
- java.lang.StringencodeForLDAP(java.lang.String input) - -
-          Encode data for use in LDAP queries.
- java.lang.StringencodeForSQL(Codec codec, - java.lang.String input) - -
-          Encode for SQL according to the selected codec.
- java.lang.StringencodeForURL(java.lang.String input) - -
-          Encode for use in a URL.
- java.lang.StringencodeForVBScript(java.lang.String input) - -
-          Encode data for insertion inside a data value in a visual basic script.
- java.lang.StringencodeForXML(java.lang.String input) - -
-          Encode data for use in an XML element.
- java.lang.StringencodeForXMLAttribute(java.lang.String input) - -
-          Encode data for use in an XML attribute.
- java.lang.StringencodeForXPath(java.lang.String input) - -
-          Encode data for use in an XPath query.
- java.lang.Stringnormalize(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
-
-
-
-
-
- -

-CHAR_PASSWORD_LETTERS

-
-public static final char[] CHAR_PASSWORD_LETTERS
-
-
-
-
- - - - - - - - - - - -
-Method Detail
- -

-canonicalize

-
-public java.lang.String canonicalize(java.lang.String input)
-                              throws EncodingException
-
-
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. -

-

-
Parameters:
input - the text to canonicalize -
Returns:
a String containing the canonicalized text -
Throws: -
EncodingException - if canonicalization fails
-
-
-
- -

-canonicalize

-
-public java.lang.String canonicalize(java.lang.String input,
-                                     boolean strict)
-                              throws EncodingException
-
-
-
Parameters:
input - the text to canonicalize
strict - true if checking for double encoding is desired, false otherwise -
Returns:
a String containing the canonicalized text -
Throws: -
EncodingException - if canonicalization fails
-
-
-
- -

-normalize

-
-public 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. For example, an accented-e character - will be changed into a regular ASCII e character. -

-

-
Parameters:
input - the text to normalize -
Returns:
a normalized String
-
-
-
- -

-encodeForCSS

-
-public java.lang.String encodeForCSS(java.lang.String input)
-
-
Encode data for use in Cascading Style Sheets (CSS) content. -

-

-
Parameters:
input - the text to encode for CSS -
Returns:
input encoded for CSS
-
-
-
- -

-encodeForHTML

-
-public java.lang.String encodeForHTML(java.lang.String input)
-
-
Encode data for use in HTML content. -

-

-
Parameters:
input - the text to encode for HTML -
Returns:
input encoded for HTML
-
-
-
- -

-encodeForHTMLAttribute

-
-public java.lang.String encodeForHTMLAttribute(java.lang.String input)
-
-
Encode data for use in HTML attributes. -

-

-
Parameters:
input - the text to encode for an HTML attribute -
Returns:
input encoded for use as an HTML attribute
-
-
-
- -

-encodeForJavaScript

-
-public java.lang.String encodeForJavaScript(java.lang.String input)
-
-
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. -

-

-
Parameters:
input - the text to encode for JavaScript -
Returns:
input encoded for use in JavaScript
-
-
-
- -

-encodeForVBScript

-
-public java.lang.String encodeForVBScript(java.lang.String input)
-
-
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. -

-

-
Parameters:
input - the text to encode for VBScript -
Returns:
input encoded for use in VBScript
-
-
-
- -

-encodeForSQL

-
-public java.lang.String encodeForSQL(Codec codec,
-                                     java.lang.String input)
-
-
Encode for SQL according to the selected codec. -

-

-
Parameters:
codec - a Codec that declares which database 'input' is being encoded for (ie. MySQL, Oracle, etc.)
input - the text to encode for SQL -
Returns:
input encoded for use in SQL
-
-
-
- -

-encodeForLDAP

-
-public java.lang.String encodeForLDAP(java.lang.String input)
-
-
Encode data for use in LDAP queries. -

-

-
Parameters:
input - the text to encode for LDAP -
Returns:
input encoded for use in LDAP
-
-
-
- -

-encodeForDN

-
-public java.lang.String encodeForDN(java.lang.String input)
-
-
Encode data for use in an LDAP distinguished name. -

-

-
Parameters:
input - the text to encode for an LDAP distinguished name -
Returns:
input encoded for use in an LDAP distinguished name
-
-
-
- -

-encodeForXPath

-
-public java.lang.String encodeForXPath(java.lang.String input)
-
-
Encode data for use in an XPath query. -

-

-
Parameters:
input - the text to encode for XPath -
Returns:
input encoded for use in XPath
-
-
-
- -

-encodeForXML

-
-public java.lang.String encodeForXML(java.lang.String input)
-
-
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. -

-

-
Parameters:
input - the text to encode for XML -
Returns:
input encoded for use in XML
-
-
-
- -

-encodeForXMLAttribute

-
-public java.lang.String encodeForXMLAttribute(java.lang.String input)
-
-
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 -
Returns:
input encoded for use in an XML attribute
-
-
-
- -

-encodeForURL

-
-public java.lang.String encodeForURL(java.lang.String input)
-                              throws EncodingException
-
-
Encode for use in a URL. This method performs URL encoding" - on the entire string. -

-

-
Parameters:
input - the text to encode for use in a URL -
Returns:
input encoded for use in a URL -
Throws: -
EncodingException - if encoding fails
-
-
-
- -

-decodeFromURL

-
-public java.lang.String decodeFromURL(java.lang.String input)
-                               throws EncodingException
-
-
Decode from URL. Implementations should first canonicalize and - detect any double-encoding. If this check passes, then the data is decoded using URL - decoding. -

-

-
Parameters:
input - the text to decode from an encoded URL -
Returns:
the decoded URL value -
Throws: -
EncodingException - if decoding fails
-
-
-
- -

-encodeForBase64

-
-public java.lang.String encodeForBase64(byte[] input,
-                                        boolean wrap)
-
-
Encode for Base64. -

-

-
Parameters:
input - the text to encode for Base64
wrap - -
Returns:
input encoded for Base64
-
-
-
- -

-decodeFromBase64

-
-public byte[] decodeFromBase64(java.lang.String input)
-                        throws java.io.IOException
-
-
Decode data encoded with BASE-64 encoding. -

-

-
Parameters:
input - the Base64 text to decode -
Returns:
input decoded from Base64 -
Throws: -
java.io.IOException
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/EncoderTest.html b/javadoc/org/owasp/esapi/EncoderTest.html deleted file mode 100644 index d6346393f..000000000 --- a/javadoc/org/owasp/esapi/EncoderTest.html +++ /dev/null @@ -1,658 +0,0 @@ - - - - - - -EncoderTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class EncoderTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.EncoderTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class EncoderTest
extends junit.framework.TestCase
- -

-The Class EncoderTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
EncoderTest(java.lang.String testName) - -
-          Instantiates a new encoder test.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestCanonicalize() - -
-          Test of canonicalize method, of class org.owasp.esapi.Validator.
- voidtestDecodeFromBase64() - -
-          Test of decodeFromBase64 method, of class org.owasp.esapi.Encoder.
- voidtestDecodeFromURL() - -
-          Test of decodeFromURL method, of class org.owasp.esapi.Encoder.
- voidtestEncodeForBase64() - -
-          Test of encodeForBase64 method, of class org.owasp.esapi.Encoder.
- voidtestEncodeForDN() - -
-          Test of encodeForLDAP method, of class org.owasp.esapi.Encoder.
- voidtestEncodeForHTML() - -
-          Test of encodeForHTML method, of class org.owasp.esapi.Encoder.
- voidtestEncodeForHTMLAttribute() - -
-          Test of encodeForHTMLAttribute method, of class org.owasp.esapi.Encoder.
- voidtestEncodeForJavascript() - -
-          Test of encodeForJavaScript method, of class org.owasp.esapi.Encoder.
- voidtestEncodeForLDAP() - -
-          Test of encodeForLDAP method, of class org.owasp.esapi.Encoder.
- voidtestEncodeForSQL() - -
-          Test of encodeForSQL method, of class org.owasp.esapi.Encoder.
- voidtestEncodeForURL() - -
-          Test of encodeForURL method, of class org.owasp.esapi.Encoder.
- voidtestEncodeForVBScript() - -
-          Test of encodeForVisualBasicScript method, of class - org.owasp.esapi.Encoder.
- voidtestEncodeForXML() - -
-          Test of encodeForXML method, of class org.owasp.esapi.Encoder.
- voidtestEncodeForXMLAttribute() - -
-          Test of encodeForXMLAttribute method, of class org.owasp.esapi.Encoder.
- voidtestEncodeForXPath() - -
-          Test of encodeForXPath method, of class org.owasp.esapi.Encoder.
- voidtestEntityEncode() - -
-           
- voidtestNormalize() - -
-          Test of normalize method, of class org.owasp.esapi.Validator.
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-EncoderTest

-
-public EncoderTest(java.lang.String testName)
-
-
Instantiates a new encoder test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testCanonicalize

-
-public void testCanonicalize()
-                      throws EncodingException
-
-
Test of canonicalize method, of class org.owasp.esapi.Validator. -

-

- -
Throws: -
ValidationException -
EncodingException
-
-
-
- -

-testNormalize

-
-public void testNormalize()
-                   throws ValidationException
-
-
Test of normalize method, of class org.owasp.esapi.Validator. -

-

- -
Throws: -
ValidationException - the validation exception
-
-
-
- -

-testEntityEncode

-
-public void testEntityEncode()
-
-
-
-
-
-
- -

-testEncodeForHTML

-
-public void testEncodeForHTML()
-
-
Test of encodeForHTML method, of class org.owasp.esapi.Encoder. -

-

-
-
-
-
- -

-testEncodeForHTMLAttribute

-
-public void testEncodeForHTMLAttribute()
-
-
Test of encodeForHTMLAttribute method, of class org.owasp.esapi.Encoder. -

-

-
-
-
-
- -

-testEncodeForJavascript

-
-public void testEncodeForJavascript()
-
-
Test of encodeForJavaScript method, of class org.owasp.esapi.Encoder. -

-

-
-
-
-
- -

-testEncodeForVBScript

-
-public void testEncodeForVBScript()
-
-
Test of encodeForVisualBasicScript method, of class - org.owasp.esapi.Encoder. -

-

-
-
-
-
- -

-testEncodeForXPath

-
-public void testEncodeForXPath()
-
-
Test of encodeForXPath method, of class org.owasp.esapi.Encoder. -

-

-
-
-
-
- -

-testEncodeForSQL

-
-public void testEncodeForSQL()
-
-
Test of encodeForSQL method, of class org.owasp.esapi.Encoder. -

-

-
-
-
-
- -

-testEncodeForLDAP

-
-public void testEncodeForLDAP()
-
-
Test of encodeForLDAP method, of class org.owasp.esapi.Encoder. -

-

-
-
-
-
- -

-testEncodeForDN

-
-public void testEncodeForDN()
-
-
Test of encodeForLDAP method, of class org.owasp.esapi.Encoder. -

-

-
-
-
-
- -

-testEncodeForXML

-
-public void testEncodeForXML()
-
-
Test of encodeForXML method, of class org.owasp.esapi.Encoder. -

-

-
-
-
-
- -

-testEncodeForXMLAttribute

-
-public void testEncodeForXMLAttribute()
-
-
Test of encodeForXMLAttribute method, of class org.owasp.esapi.Encoder. -

-

-
-
-
-
- -

-testEncodeForURL

-
-public void testEncodeForURL()
-                      throws java.lang.Exception
-
-
Test of encodeForURL method, of class org.owasp.esapi.Encoder. -

-

- -
Throws: -
java.lang.Exception
-
-
-
- -

-testDecodeFromURL

-
-public void testDecodeFromURL()
-                       throws java.lang.Exception
-
-
Test of decodeFromURL method, of class org.owasp.esapi.Encoder. -

-

- -
Throws: -
java.lang.Exception
-
-
-
- -

-testEncodeForBase64

-
-public void testEncodeForBase64()
-
-
Test of encodeForBase64 method, of class org.owasp.esapi.Encoder. -

-

-
-
-
-
- -

-testDecodeFromBase64

-
-public void testDecodeFromBase64()
-
-
Test of decodeFromBase64 method, of class org.owasp.esapi.Encoder. -

-

-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/EncodingException.html b/javadoc/org/owasp/esapi/EncodingException.html deleted file mode 100644 index 29e6cadd7..000000000 --- a/javadoc/org/owasp/esapi/EncodingException.html +++ /dev/null @@ -1,277 +0,0 @@ - - - - - - -EncodingException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class EncodingException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.EnterpriseSecurityException
-              extended byorg.owasp.esapi.EncodingException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
-
public class EncodingException
extends EnterpriseSecurityException
- -

-An ExecutorException should be thrown for any problems that occur when - encoding or decoding data. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
EncodingException(java.lang.String userMessage, - java.lang.String logMessage) - -
-          Creates a new instance of EncodingException.
EncodingException(java.lang.String userMessage, - java.lang.String logMessage, - java.lang.Throwable cause) - -
-          Instantiates a new EncodingException.
-  - - - - - - - - - - -
Methods inherited from class org.owasp.esapi.EnterpriseSecurityException
getLogMessage, getUserMessage
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-EncodingException

-
-public EncodingException(java.lang.String userMessage,
-                         java.lang.String logMessage)
-
-
Creates a new instance of EncodingException. -

-

-
- -

-EncodingException

-
-public EncodingException(java.lang.String userMessage,
-                         java.lang.String logMessage,
-                         java.lang.Throwable cause)
-
-
Instantiates a new EncodingException. -

-

Parameters:
cause - the cause
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/EncryptedProperties.html b/javadoc/org/owasp/esapi/EncryptedProperties.html deleted file mode 100644 index 74040dff3..000000000 --- a/javadoc/org/owasp/esapi/EncryptedProperties.html +++ /dev/null @@ -1,337 +0,0 @@ - - - - - - -EncryptedProperties - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Interface EncryptedProperties

-
-
All Known Implementing Classes:
DefaultEncryptedProperties
-
-
-
-
public interface EncryptedProperties
- -

-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.StringgetProperty(java.lang.String key) - -
-          Gets the property value from the encrypted store, decrypts it, and returns the plaintext value to the caller.
- java.util.SetkeySet() - -
-          Key set.
- voidload(java.io.InputStream in) - -
-          Load.
- java.lang.StringsetProperty(java.lang.String key, - java.lang.String value) - -
-          Encrypts the plaintext property value and stores the ciphertext value in the encrypted store.
- voidstore(java.io.OutputStream out, - java.lang.String comments) - -
-          Store.
-  -

- - - - - - - - - - - - - - -
-Method Detail
- -

-getProperty

-
-public java.lang.String getProperty(java.lang.String key)
-                             throws EncryptionException
-
-
Gets the property value from the encrypted store, decrypts it, and returns the plaintext value to the caller. -

-

-
Parameters:
key - the key -
Returns:
the decrypted property value -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-setProperty

-
-public java.lang.String setProperty(java.lang.String key,
-                                    java.lang.String value)
-                             throws EncryptionException
-
-
Encrypts the plaintext property value and stores the ciphertext value in the encrypted store. -

-

-
Parameters:
key - the key
value - the value -
Returns:
the encrypted property value -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-keySet

-
-public java.util.Set keySet()
-
-
Key set. -

-

- -
Returns:
the set
-
-
-
- -

-load

-
-public void load(java.io.InputStream in)
-          throws java.io.IOException
-
-
Load. -

-

-
Parameters:
in - the in -
Throws: -
java.io.IOException - Signals that an I/O exception has occurred.
-
-
-
- -

-store

-
-public void store(java.io.OutputStream out,
-                  java.lang.String comments)
-           throws java.io.IOException
-
-
Store. -

-

-
Parameters:
out - the out
comments - the comments -
Throws: -
java.io.IOException - Signals that an I/O exception has occurred.
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/EncryptedPropertiesTest.html b/javadoc/org/owasp/esapi/EncryptedPropertiesTest.html deleted file mode 100644 index fd0dc2bf1..000000000 --- a/javadoc/org/owasp/esapi/EncryptedPropertiesTest.html +++ /dev/null @@ -1,432 +0,0 @@ - - - - - - -EncryptedPropertiesTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class EncryptedPropertiesTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.EncryptedPropertiesTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class EncryptedPropertiesTest
extends junit.framework.TestCase
- -

-The Class EncryptedPropertiesTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
EncryptedPropertiesTest(java.lang.String testName) - -
-          Instantiates a new encrypted properties test.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestGetProperty() - -
-          Test of getProperty method, of class org.owasp.esapi.EncryptedProperties.
- voidtestKeySet() - -
-          Test of keySet method, of class org.owasp.esapi.EncryptedProperties.
- voidtestLoad() - -
-          Test of load method, of class org.owasp.esapi.EncryptedProperties.
- voidtestMain() - -
-          Test of store method, of class org.owasp.esapi.EncryptedProperties.
- voidtestSetProperty() - -
-          Test of setProperty method, of class org.owasp.esapi.EncryptedProperties.
- voidtestStore() - -
-          Test of store method, of class org.owasp.esapi.EncryptedProperties.
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-EncryptedPropertiesTest

-
-public EncryptedPropertiesTest(java.lang.String testName)
-
-
Instantiates a new encrypted properties test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testGetProperty

-
-public void testGetProperty()
-                     throws EncryptionException
-
-
Test of getProperty method, of class org.owasp.esapi.EncryptedProperties. -

-

- -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-testSetProperty

-
-public void testSetProperty()
-                     throws EncryptionException
-
-
Test of setProperty method, of class org.owasp.esapi.EncryptedProperties. -

-

- -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-testKeySet

-
-public void testKeySet()
-                throws java.lang.Exception
-
-
Test of keySet method, of class org.owasp.esapi.EncryptedProperties. -

-

- -
Throws: -
java.lang.Exception
-
-
-
- -

-testLoad

-
-public void testLoad()
-              throws java.lang.Exception
-
-
Test of load method, of class org.owasp.esapi.EncryptedProperties. -

-

- -
Throws: -
java.lang.Exception
-
-
-
- -

-testStore

-
-public void testStore()
-               throws java.lang.Exception
-
-
Test of store method, of class org.owasp.esapi.EncryptedProperties. -

-

- -
Throws: -
java.lang.Exception
-
-
-
- -

-testMain

-
-public void testMain()
-              throws java.lang.Exception
-
-
Test of store method, of class org.owasp.esapi.EncryptedProperties. -

-

- -
Throws: -
java.lang.Exception
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/EncryptionException.html b/javadoc/org/owasp/esapi/EncryptionException.html deleted file mode 100644 index 3f62ce292..000000000 --- a/javadoc/org/owasp/esapi/EncryptionException.html +++ /dev/null @@ -1,277 +0,0 @@ - - - - - - -EncryptionException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class EncryptionException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.EnterpriseSecurityException
-              extended byorg.owasp.esapi.EncryptionException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
-
public class EncryptionException
extends EnterpriseSecurityException
- -

-An EncryptionException should be thrown for any problems related to - encryption, hashing, or digital signatures. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
EncryptionException(java.lang.String userMessage, - java.lang.String logMessage) - -
-          Creates a new instance of EncryptionException.
EncryptionException(java.lang.String userMessage, - java.lang.String logMessage, - java.lang.Throwable cause) - -
-          Instantiates a new EncryptionException.
-  - - - - - - - - - - -
Methods inherited from class org.owasp.esapi.EnterpriseSecurityException
getLogMessage, getUserMessage
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-EncryptionException

-
-public EncryptionException(java.lang.String userMessage,
-                           java.lang.String logMessage)
-
-
Creates a new instance of EncryptionException. -

-

-
- -

-EncryptionException

-
-public EncryptionException(java.lang.String userMessage,
-                           java.lang.String logMessage,
-                           java.lang.Throwable cause)
-
-
Instantiates a new EncryptionException. -

-

Parameters:
cause - the cause
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/Encryptor.html b/javadoc/org/owasp/esapi/Encryptor.html deleted file mode 100644 index 588dcd5e2..000000000 --- a/javadoc/org/owasp/esapi/Encryptor.html +++ /dev/null @@ -1,491 +0,0 @@ - - - - - - -Encryptor - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Interface Encryptor

-
-
All Known Implementing Classes:
JavaEncryptor
-
-
-
-
public interface Encryptor
- -

-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.Stringdecrypt(java.lang.String ciphertext) - -
-          Decrypts the provided ciphertext string (encrypted with the encrypt - method) and returns a plaintext string.
- java.lang.Stringencrypt(java.lang.String plaintext) - -
-          Encrypts the provided plaintext and returns a ciphertext string.
- longgetRelativeTimeStamp(long offset) - -
-          Gets an absolute timestamp representing an offset from the current time to be used by - other functions in the library.
- longgetTimeStamp() - -
-          Gets a timestamp representing the current date and time to be used by - other functions in the library.
- java.lang.Stringhash(java.lang.String plaintext, - java.lang.String salt) - -
-          Returns a string representation of the hash of the provided plaintext and - salt.
- java.lang.Stringseal(java.lang.String data, - long timestamp) - -
-          Creates a seal that binds a set of data and includes an expiration timestamp.
- java.lang.Stringsign(java.lang.String data) - -
-          Create a digital signature for the provided data and return it in a - string.
- java.lang.Stringunseal(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.
- booleanverifySeal(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.
- booleanverifySignature(java.lang.String signature, - java.lang.String data) - -
-          Verifies a digital signature (created with the sign method) and returns - the boolean result.
-  -

- - - - - - - - - - - - - - -
-Method Detail
- -

-hash

-
-public java.lang.String hash(java.lang.String plaintext,
-                             java.lang.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. -

-

-
Parameters:
plaintext - the plaintext String to encrypt
salt - the salt -
Returns:
the encrypted hash of 'plaintext' stored as a String -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-encrypt

-
-public java.lang.String encrypt(java.lang.String plaintext)
-                         throws EncryptionException
-
-
Encrypts the provided plaintext and returns a ciphertext string. -

-

-
Parameters:
plaintext - the plaintext String to encrypt -
Returns:
the encrypted String -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-decrypt

-
-public java.lang.String decrypt(java.lang.String ciphertext)
-                         throws EncryptionException
-
-
Decrypts the provided ciphertext string (encrypted with the encrypt - method) and returns a plaintext string. -

-

-
Parameters:
ciphertext - the ciphertext -
Returns:
the decrypted ciphertext -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-sign

-
-public java.lang.String sign(java.lang.String data)
-                      throws EncryptionException
-
-
Create a digital signature for the provided data and return it in a - string. -

-

-
Parameters:
data - the data to sign -
Returns:
the digital signature stored as a String -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-verifySignature

-
-public boolean verifySignature(java.lang.String signature,
-                               java.lang.String data)
-
-
Verifies a digital signature (created with the sign method) and returns - the boolean result. -

-

-
Parameters:
signature - the signature to verify
data - the data to verify -
Returns:
true, if the signature is verified -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-seal

-
-public java.lang.String seal(java.lang.String data,
-                             long timestamp)
-                      throws IntegrityException
-
-
Creates a seal that binds a set of data and includes an expiration timestamp. -

-

-
Parameters:
data - the data to seal
timestamp - the absolute expiration date of the data, expressed as seconds since the epoch -
Returns:
the seal -
Throws: -
EncryptionException - the encryption exception -
IntegrityException
-
-
-
- -

-unseal

-
-public java.lang.String unseal(java.lang.String seal)
-                        throws EncryptionException
-
-
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 -
EncryptionException
-
-
-
- -

-verifySeal

-
-public 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. -

-

-
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. -

-

- -
Returns:
the timestamp
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/EncryptorTest.html b/javadoc/org/owasp/esapi/EncryptorTest.html deleted file mode 100644 index 52814926a..000000000 --- a/javadoc/org/owasp/esapi/EncryptorTest.html +++ /dev/null @@ -1,455 +0,0 @@ - - - - - - -EncryptorTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class EncryptorTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.EncryptorTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class EncryptorTest
extends junit.framework.TestCase
- -

-The Class EncryptorTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
EncryptorTest(java.lang.String testName) - -
-          Instantiates a new encryptor test.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestDecrypt() - -
-          Test of decrypt method, of class org.owasp.esapi.Encryptor.
- voidtestEncrypt() - -
-          Test of encrypt method, of class org.owasp.esapi.Encryptor.
- voidtestHash() - -
-          Test of hash method, of class org.owasp.esapi.Encryptor.
- voidtestSeal() - -
-          Test of seal method, of class org.owasp.esapi.Encryptor.
- voidtestSign() - -
-          Test of sign method, of class org.owasp.esapi.Encryptor.
- voidtestVerifySeal() - -
-          Test of verifySeal method, of class org.owasp.esapi.Encryptor.
- voidtestVerifySignature() - -
-          Test of verifySignature method, of class org.owasp.esapi.Encryptor.
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-EncryptorTest

-
-public EncryptorTest(java.lang.String testName)
-
-
Instantiates a new encryptor test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testHash

-
-public void testHash()
-              throws EncryptionException
-
-
Test of hash method, of class org.owasp.esapi.Encryptor. -

-

- -
Throws: -
EncryptionException
-
-
-
- -

-testEncrypt

-
-public void testEncrypt()
-                 throws EncryptionException
-
-
Test of encrypt method, of class org.owasp.esapi.Encryptor. -

-

- -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-testDecrypt

-
-public void testDecrypt()
-
-
Test of decrypt method, of class org.owasp.esapi.Encryptor. -

-

-
-
-
-
- -

-testSign

-
-public void testSign()
-              throws EncryptionException
-
-
Test of sign method, of class org.owasp.esapi.Encryptor. -

-

- -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-testVerifySignature

-
-public void testVerifySignature()
-                         throws EncryptionException
-
-
Test of verifySignature method, of class org.owasp.esapi.Encryptor. -

-

- -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-testSeal

-
-public void testSeal()
-              throws IntegrityException
-
-
Test of seal method, of class org.owasp.esapi.Encryptor. -

-

- -
Throws: -
EncryptionException - the encryption exception -
IntegrityException
-
-
-
- -

-testVerifySeal

-
-public void testVerifySeal()
-                    throws EnterpriseSecurityException
-
-
Test of verifySeal method, of class org.owasp.esapi.Encryptor. -

-

- -
Throws: -
EncryptionException - the encryption exception -
EnterpriseSecurityException
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/EnterpriseSecurityException.html b/javadoc/org/owasp/esapi/EnterpriseSecurityException.html deleted file mode 100644 index fe4733e9d..000000000 --- a/javadoc/org/owasp/esapi/EnterpriseSecurityException.html +++ /dev/null @@ -1,334 +0,0 @@ - - - - - - -EnterpriseSecurityException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class EnterpriseSecurityException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.EnterpriseSecurityException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
Direct Known Subclasses:
AccessControlException, AuthenticationException, AvailabilityException, CertificateException, EncodingException, EncryptionException, ExecutorException, IntegrityException, ValidationException
-
-
-
-
public class EnterpriseSecurityException
extends java.lang.Exception
- -

-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. -

-

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
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.
-  - - - - - - - - - - - - - - - -
-Method Summary
- java.lang.StringgetLogMessage() - -
-           
- java.lang.StringgetUserMessage() - -
-           
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-EnterpriseSecurityException

-
-public EnterpriseSecurityException(java.lang.String userMessage,
-                                   java.lang.String logMessage)
-
-
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. -

-

-
- -

-EnterpriseSecurityException

-
-public 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. -

-

Parameters:
cause - the cause
- - - - - - - - -
-Method Detail
- -

-getUserMessage

-
-public java.lang.String getUserMessage()
-
-
-
-
-
-
- -

-getLogMessage

-
-public java.lang.String getLogMessage()
-
-
-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/Executor.html b/javadoc/org/owasp/esapi/Executor.html deleted file mode 100644 index e25c8a67b..000000000 --- a/javadoc/org/owasp/esapi/Executor.html +++ /dev/null @@ -1,253 +0,0 @@ - - - - - - -Executor - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Interface Executor

-
-
All Known Implementing Classes:
DefaultExecutor
-
-
-
-
public interface Executor
- -

-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.StringexecuteSystemCommand(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.
-  -

- - - - - - - - - - - - - - -
-Method Detail
- -

-executeSystemCommand

-
-public java.lang.String executeSystemCommand(java.io.File executable,
-                                             java.util.List params,
-                                             java.io.File workdir,
-                                             int timeoutSeconds)
-                                      throws ExecutorException
-
-
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 -
Returns:
the output of the command being run -
Throws: -
ExecutorException - the service exception
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/ExecutorException.html b/javadoc/org/owasp/esapi/ExecutorException.html deleted file mode 100644 index 89b717f33..000000000 --- a/javadoc/org/owasp/esapi/ExecutorException.html +++ /dev/null @@ -1,277 +0,0 @@ - - - - - - -ExecutorException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class ExecutorException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.EnterpriseSecurityException
-              extended byorg.owasp.esapi.ExecutorException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
-
public class ExecutorException
extends EnterpriseSecurityException
- -

-An ExecutorException should be thrown for any problems that arise during the - execution of a system executable. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
ExecutorException(java.lang.String userMessage, - java.lang.String logMessage) - -
-          Creates a new instance of ExecutorException.
ExecutorException(java.lang.String userMessage, - java.lang.String logMessage, - java.lang.Throwable cause) - -
-          Instantiates a new ExecutorException.
-  - - - - - - - - - - -
Methods inherited from class org.owasp.esapi.EnterpriseSecurityException
getLogMessage, getUserMessage
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-ExecutorException

-
-public ExecutorException(java.lang.String userMessage,
-                         java.lang.String logMessage)
-
-
Creates a new instance of ExecutorException. -

-

-
- -

-ExecutorException

-
-public ExecutorException(java.lang.String userMessage,
-                         java.lang.String logMessage,
-                         java.lang.Throwable cause)
-
-
Instantiates a new ExecutorException. -

-

Parameters:
cause - the cause
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/ExecutorTest.html b/javadoc/org/owasp/esapi/ExecutorTest.html deleted file mode 100644 index 4de6b8a1b..000000000 --- a/javadoc/org/owasp/esapi/ExecutorTest.html +++ /dev/null @@ -1,312 +0,0 @@ - - - - - - -ExecutorTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class ExecutorTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.ExecutorTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class ExecutorTest
extends junit.framework.TestCase
- -

-The Class ExecutorTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
ExecutorTest(java.lang.String testName) - -
-          Instantiates a new executor test.
-  - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestExecuteSystemCommand() - -
-          Test of executeOSCommand method, of class org.owasp.esapi.Executor
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-ExecutorTest

-
-public ExecutorTest(java.lang.String testName)
-
-
Instantiates a new executor test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testExecuteSystemCommand

-
-public void testExecuteSystemCommand()
-                              throws java.lang.Exception
-
-
Test of executeOSCommand method, of class org.owasp.esapi.Executor -

-

- -
Throws: -
java.lang.Exception - the exception
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/HTTPUtilities.html b/javadoc/org/owasp/esapi/HTTPUtilities.html deleted file mode 100644 index dcd228b1c..000000000 --- a/javadoc/org/owasp/esapi/HTTPUtilities.html +++ /dev/null @@ -1,910 +0,0 @@ - - - - - - -HTTPUtilities - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Interface HTTPUtilities

-
-
All Known Implementing Classes:
DefaultHTTPUtilities
-
-
-
-
public interface HTTPUtilities
- -

-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
-
-
- -

- - - - - - - - - - - - - - -
-Field Summary
-static java.lang.StringREMEMBER_TOKEN_COOKIE_NAME - -
-          Key for remember token cookie
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- java.lang.StringaddCSRFToken(java.lang.String href) - -
-          Adds the current user's CSRF token (see User.getCSRFToken()) to the URL for purposes of preventing CSRF attacks.
- voidassertSecureRequest(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.HttpSessionchangeSessionIdentifier(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.StringdecryptHiddenField(java.lang.String encrypted) - -
-          Decrypts an encrypted hidden field value and returns the cleartext.
- java.util.MapdecryptQueryString(java.lang.String encrypted) - -
-          Takes an encrypted querystring and returns a Map containing the original parameters.
- java.util.MapdecryptStateFromCookie(javax.servlet.http.HttpServletRequest request) - -
-          Retrieves a map of data from a cookie encrypted with encryptStateInCookie().
- java.lang.StringencryptHiddenField(java.lang.String value) - -
-          Encrypts a hidden field value for use in HTML.
- java.lang.StringencryptQueryString(java.lang.String query) - -
-          Takes a querystring (i.e.
- voidencryptStateInCookie(javax.servlet.http.HttpServletResponse response, - java.util.Map cleartext) - -
-          Stores a Map of data in an encrypted cookie.
- javax.servlet.http.CookiegetCookie(javax.servlet.http.HttpServletRequest request, - java.lang.String name) - -
-          Get the first cookie with the matching name.
- java.lang.StringgetCSRFToken() - -
-          Returns the current user's CSRF token.
- SafeRequestgetCurrentRequest() - -
-          Retrieves the current HttpServletRequest
- SafeResponsegetCurrentResponse() - -
-          Retrieves the current HttpServletResponse
- java.util.ListgetSafeFileUploads(javax.servlet.http.HttpServletRequest request, - java.io.File tempDir, - java.io.File finalDir) - -
-          Extract uploaded files from a multipart HTTP requests.
- voidkillAllCookies(javax.servlet.http.HttpServletRequest request, - javax.servlet.http.HttpServletResponse response) - -
-          Kill all cookies received in the last request from the browser.
- voidkillCookie(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.
- voidlogHTTPRequest(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.
- voidlogHTTPRequest(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.
- voidsafeSendForward(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.
- voidsafeSetContentType(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.
- voidsetCurrentHTTP(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)
- voidsetNoCacheHeaders(javax.servlet.http.HttpServletResponse response) - -
-          Set headers to protect sensitive information against being cached in the browser.
- java.lang.StringsetRememberToken(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.
- voidverifyCSRFToken(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
-
-
Key for remember token cookie -

-

-
See Also:
Constant Field Values
-
- - - - - - - - - - - -
-Method Detail
- -

-assertSecureRequest

-
-public void assertSecureRequest(javax.servlet.http.HttpServletRequest request)
-                         throws AccessControlException
-
-
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 -

-

- -
Throws: -
AccessControlException - if security constraints are not met
-
-
-
- -

-addCSRFToken

-
-public 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. - 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
-
-
-
- -

-getCookie

-
-public javax.servlet.http.Cookie getCookie(javax.servlet.http.HttpServletRequest request,
-                                           java.lang.String name)
-
-
Get the first cookie with the matching name. -

-

-
Parameters:
name - -
Returns:
-
-
-
- -

-getCSRFToken

-
-public java.lang.String getCSRFToken()
-
-
Returns the current user's CSRF token. If there is no current user then return null. -

-

- -
Returns:
the current users CSRF token
-
-
-
- -

-changeSessionIdentifier

-
-public javax.servlet.http.HttpSession changeSessionIdentifier(javax.servlet.http.HttpServletRequest request)
-                                                       throws AuthenticationException
-
-
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 -

-

- -
Returns:
the new HttpSession with a changed id -
Throws: -
EnterpriseSecurityException - the enterprise security exception -
AuthenticationException
-
-
-
- -

-verifyCSRFToken

-
-public void verifyCSRFToken(javax.servlet.http.HttpServletRequest request)
-                     throws IntrusionException
-
-
Checks the CSRF token in the URL (see User.getCSRFToken()) against the user's CSRF token and - throws an IntrusionException if it is missing. -

-

- -
Throws: -
IntrusionException - if CSRF token is missing or incorrect
-
-
-
- -

-decryptHiddenField

-
-public java.lang.String decryptHiddenField(java.lang.String encrypted)
-
-
Decrypts an encrypted hidden field value and returns the cleartext. If the field does not decrypt properly, - an IntrusionException is thrown to indicate tampering. -

-

-
Parameters:
encrypted - hidden field value to decrypt -
Returns:
decrypted hidden field value stored as a String
-
-
-
- -

-setRememberToken

-
-public 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. 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 -
Returns:
encrypted "Remember Me" token stored as a String
-
-
-
- -

-encryptHiddenField

-
-public java.lang.String encryptHiddenField(java.lang.String value)
-                                    throws EncryptionException
-
-
Encrypts a hidden field value for use in HTML. -

-

-
Parameters:
value - the cleartext value of the hidden field -
Returns:
the encrypted value of the hidden field -
Throws: -
EncryptionException
-
-
-
- -

-encryptQueryString

-
-public java.lang.String encryptQueryString(java.lang.String query)
-                                    throws EncryptionException
-
-
Takes a querystring (i.e. everything after the ? in the URL) and returns an encrypted string containing the parameters. -

-

-
Parameters:
query - the querystring to encrypt -
Returns:
encrypted querystring stored as a String -
Throws: -
EncryptionException
-
-
-
- -

-decryptQueryString

-
-public java.util.Map decryptQueryString(java.lang.String encrypted)
-                                 throws EncryptionException
-
-
Takes an encrypted querystring and returns a Map containing the original parameters. -

-

-
Parameters:
encrypted - the encrypted querystring to decrypt -
Returns:
a Map object containing the decrypted querystring -
Throws: -
EncryptionException
-
-
-
- -

-getSafeFileUploads

-
-public java.util.List getSafeFileUploads(javax.servlet.http.HttpServletRequest request,
-                                         java.io.File tempDir,
-                                         java.io.File finalDir)
-                                  throws ValidationException
-
-
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 -

-

-
Parameters:
tempDir - the temporary directory
finalDir - the final directory -
Returns:
List of new File objects from upload -
Throws: -
ValidationException - if the file fails validation
-
-
-
- -

-decryptStateFromCookie

-
-public java.util.Map decryptStateFromCookie(javax.servlet.http.HttpServletRequest request)
-                                     throws EncryptionException
-
-
Retrieves a map of data from a cookie encrypted with encryptStateInCookie(). -

-

- -
Returns:
a map containing the decrypted cookie state value -
Throws: -
EncryptionException
-
-
-
- -

-killAllCookies

-
-public void killAllCookies(javax.servlet.http.HttpServletRequest request,
-                           javax.servlet.http.HttpServletResponse response)
-
-
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(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. Note that this - method does not delete new cookies that are being set by the application for this response. -

-

-
-
-
-
- -

-encryptStateInCookie

-
-public void encryptStateInCookie(javax.servlet.http.HttpServletResponse response,
-                                 java.util.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. -

-

- -
Throws: -
EncryptionException
-
-
-
- -

-safeSendForward

-
-public void safeSendForward(javax.servlet.http.HttpServletRequest request,
-                            javax.servlet.http.HttpServletResponse response,
-                            java.lang.String context,
-                            java.lang.String location)
-                     throws AccessControlException,
-                            javax.servlet.ServletException,
-                            java.io.IOException
-
-
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.
location - the URL to forward to -
Throws: -
AccessControlException -
javax.servlet.ServletException -
java.io.IOException
-
-
-
- -

-safeSetContentType

-
-public 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. -

-

-
-
-
-
- -

-setNoCacheHeaders

-
-public void setNoCacheHeaders(javax.servlet.http.HttpServletResponse response)
-
-
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: - -
- 
- Cache-Control: no-store
- Cache-Control: no-cache
- Cache-Control: must-revalidate
- Expires: -1
- -
- - 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: - - - This method uses getCurrentResponse() to obtain the HttpServletResponse object -

-

-
-
-
-
- -

-setCurrentHTTP

-
-public 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) -

-

-
Parameters:
request - the current request
response - the current response
-
-
-
- -

-getCurrentRequest

-
-public SafeRequest getCurrentRequest()
-
-
Retrieves the current HttpServletRequest -

-

- -
Returns:
the current request
-
-
-
- -

-getCurrentResponse

-
-public SafeResponse getCurrentResponse()
-
-
Retrieves the current HttpServletResponse -

-

- -
Returns:
the current response
-
-
-
- -

-logHTTPRequest

-
-public 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. Be careful not - to log sensitive information, and consider masking with the - logHTTPRequest( List parameterNamesToObfuscate ) method. -

-

-
Parameters:
logger - the logger to write the request to
-
-
-
- -

-logHTTPRequest

-
-public 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. 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
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/HTTPUtilitiesTest.html b/javadoc/org/owasp/esapi/HTTPUtilitiesTest.html deleted file mode 100644 index da1ec5cc7..000000000 --- a/javadoc/org/owasp/esapi/HTTPUtilitiesTest.html +++ /dev/null @@ -1,532 +0,0 @@ - - - - - - -HTTPUtilitiesTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class HTTPUtilitiesTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.HTTPUtilitiesTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class HTTPUtilitiesTest
extends junit.framework.TestCase
- -

-The Class HTTPUtilitiesTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
HTTPUtilitiesTest(java.lang.String testName) - -
-          Instantiates a new HTTP utilities test.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestAddCSRFToken() - -
-          Test of addCSRFToken method, of class org.owasp.esapi.HTTPUtilities.
- voidtestChangeSessionIdentifier() - -
-          Test of sendRedirect method, of class org.owasp.esapi.HTTPUtilities.
- voidtestGetFileUploads() - -
-          Test of formatHttpRequestForLog method, of class org.owasp.esapi.HTTPUtilities.
- voidtestGetStateFromEncryptedCookie() - -
-           
- voidtestIsValidHTTPRequest() - -
-          Test of isValidHTTPRequest method, of class org.owasp.esapi.HTTPUtilities.
- voidtestKillAllCookies() - -
-          Test of killAllCookies method, of class org.owasp.esapi.HTTPUtilities.
- voidtestKillCookie() - -
-          Test of killCookie method, of class org.owasp.esapi.HTTPUtilities.
- voidtestSaveStateInEncryptedCookie() - -
-           
- voidtestSendSafeRedirect() - -
-          Test of sendRedirect method, of class org.owasp.esapi.HTTPUtilities.
- voidtestSetCookie() - -
-          Test of setCookie method, of class org.owasp.esapi.HTTPUtilities.
- voidtestSetNoCacheHeaders() - -
-          Test set no cache headers.
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-HTTPUtilitiesTest

-
-public HTTPUtilitiesTest(java.lang.String testName)
-
-
Instantiates a new HTTP utilities test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testAddCSRFToken

-
-public void testAddCSRFToken()
-                      throws AuthenticationException
-
-
Test of addCSRFToken method, of class org.owasp.esapi.HTTPUtilities. -

-

- -
Throws: -
AuthenticationException
-
-
-
- -

-testChangeSessionIdentifier

-
-public void testChangeSessionIdentifier()
-                                 throws EnterpriseSecurityException
-
-
Test of sendRedirect method, of class org.owasp.esapi.HTTPUtilities. -

-

- -
Throws: -
ValidationException - the validation exception -
java.io.IOException - Signals that an I/O exception has occurred. -
AuthenticationException - the authentication exception -
EnterpriseSecurityException
-
-
-
- -

-testGetFileUploads

-
-public void testGetFileUploads()
-                        throws java.io.IOException
-
-
Test of formatHttpRequestForLog method, of class org.owasp.esapi.HTTPUtilities. -

-

- -
Throws: -
java.io.IOException
-
-
-
- -

-testIsValidHTTPRequest

-
-public void testIsValidHTTPRequest()
-
-
Test of isValidHTTPRequest method, of class org.owasp.esapi.HTTPUtilities. -

-

-
-
-
-
- -

-testKillAllCookies

-
-public void testKillAllCookies()
-
-
Test of killAllCookies method, of class org.owasp.esapi.HTTPUtilities. -

-

-
-
-
-
- -

-testKillCookie

-
-public void testKillCookie()
-
-
Test of killCookie method, of class org.owasp.esapi.HTTPUtilities. -

-

-
-
-
-
- -

-testSendSafeRedirect

-
-public void testSendSafeRedirect()
-                          throws ValidationException,
-                                 java.io.IOException
-
-
Test of sendRedirect method, of class org.owasp.esapi.HTTPUtilities. -

-

- -
Throws: -
ValidationException - the validation exception -
java.io.IOException - Signals that an I/O exception has occurred.
-
-
-
- -

-testSetCookie

-
-public void testSetCookie()
-
-
Test of setCookie method, of class org.owasp.esapi.HTTPUtilities. -

-

-
-
-
-
- -

-testGetStateFromEncryptedCookie

-
-public void testGetStateFromEncryptedCookie()
-
-
-
-
-
-
- -

-testSaveStateInEncryptedCookie

-
-public void testSaveStateInEncryptedCookie()
-
-
-
-
-
-
- -

-testSetNoCacheHeaders

-
-public void testSetNoCacheHeaders()
-
-
Test set no cache headers. -

-

-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/IntegrityException.html b/javadoc/org/owasp/esapi/IntegrityException.html deleted file mode 100644 index e5ff44b47..000000000 --- a/javadoc/org/owasp/esapi/IntegrityException.html +++ /dev/null @@ -1,278 +0,0 @@ - - - - - - -IntegrityException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class IntegrityException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.EnterpriseSecurityException
-              extended byorg.owasp.esapi.IntegrityException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
-
public class IntegrityException
extends EnterpriseSecurityException
- -

-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. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
IntegrityException(java.lang.String userMessage, - java.lang.String logMessage) - -
-          Creates a new instance of IntegrityException.
IntegrityException(java.lang.String userMessage, - java.lang.String logMessage, - java.lang.Throwable cause) - -
-          Instantiates a new IntegrityException.
-  - - - - - - - - - - -
Methods inherited from class org.owasp.esapi.EnterpriseSecurityException
getLogMessage, getUserMessage
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-IntegrityException

-
-public IntegrityException(java.lang.String userMessage,
-                          java.lang.String logMessage)
-
-
Creates a new instance of IntegrityException. -

-

-
- -

-IntegrityException

-
-public IntegrityException(java.lang.String userMessage,
-                          java.lang.String logMessage,
-                          java.lang.Throwable cause)
-
-
Instantiates a new IntegrityException. -

-

Parameters:
cause - the cause
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/IntrusionDetector.html b/javadoc/org/owasp/esapi/IntrusionDetector.html deleted file mode 100644 index 525b3d328..000000000 --- a/javadoc/org/owasp/esapi/IntrusionDetector.html +++ /dev/null @@ -1,264 +0,0 @@ - - - - - - -IntrusionDetector - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Interface IntrusionDetector

-
-
All Known Implementing Classes:
DefaultIntrusionDetector
-
-
-
-
public interface IntrusionDetector
- -

-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
- voidaddEvent(java.lang.String eventName, - java.lang.String logMessage) - -
-          Adds the event to the IntrusionDetector.
- voidaddException(java.lang.Exception exception) - -
-          Adds the exception to the IntrusionDetector.
-  -

- - - - - - - - - - - - - - -
-Method Detail
- -

-addException

-
-public void addException(java.lang.Exception exception)
-                  throws IntrusionException
-
-
Adds the exception to the IntrusionDetector. -

-

-
Parameters:
exception - the exception -
Throws: -
IntrusionException - the intrusion exception
-
-
-
- -

-addEvent

-
-public void addEvent(java.lang.String eventName,
-                     java.lang.String logMessage)
-              throws IntrusionException
-
-
Adds the event to the IntrusionDetector. -

-

-
Parameters:
eventName - the event
logMessage - the message to log with the event -
Throws: -
IntrusionException - the intrusion exception
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/IntrusionDetectorTest.html b/javadoc/org/owasp/esapi/IntrusionDetectorTest.html deleted file mode 100644 index ef04439d6..000000000 --- a/javadoc/org/owasp/esapi/IntrusionDetectorTest.html +++ /dev/null @@ -1,336 +0,0 @@ - - - - - - -IntrusionDetectorTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class IntrusionDetectorTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.IntrusionDetectorTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class IntrusionDetectorTest
extends junit.framework.TestCase
- -

-The Class IntrusionDetectorTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
IntrusionDetectorTest(java.lang.String testName) - -
-          Instantiates a new intrusion detector test.
-  - - - - - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestAddEvent() - -
-          Test of addEvent method, of class org.owasp.esapi.IntrusionDetector.
- voidtestAddException() - -
-          Test of addException method, of class org.owasp.esapi.IntrusionDetector.
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-IntrusionDetectorTest

-
-public IntrusionDetectorTest(java.lang.String testName)
-
-
Instantiates a new intrusion detector test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testAddException

-
-public void testAddException()
-                      throws AuthenticationException
-
-
Test of addException method, of class org.owasp.esapi.IntrusionDetector. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testAddEvent

-
-public void testAddEvent()
-                  throws AuthenticationException
-
-
Test of addEvent method, of class org.owasp.esapi.IntrusionDetector. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/IntrusionException.html b/javadoc/org/owasp/esapi/IntrusionException.html deleted file mode 100644 index 55308f335..000000000 --- a/javadoc/org/owasp/esapi/IntrusionException.html +++ /dev/null @@ -1,341 +0,0 @@ - - - - - - -IntrusionException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class IntrusionException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byjava.lang.RuntimeException
-              extended byorg.owasp.esapi.IntrusionException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
-
public class IntrusionException
extends java.lang.RuntimeException
- -

-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. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - - - - -
-Constructor Summary
IntrusionException() - -
-          Internal classes may throw an IntrusionException to the IntrusionDetector, which generates the appropriate log - message.
IntrusionException(java.lang.String userMessage, - java.lang.String logMessage) - -
-          Creates a new instance of IntrusionException.
IntrusionException(java.lang.String userMessage, - java.lang.String logMessage, - java.lang.Throwable cause) - -
-          Instantiates a new intrusion exception.
-  - - - - - - - - - - - - - - - -
-Method Summary
- java.lang.StringgetLogMessage() - -
-           
- java.lang.StringgetUserMessage() - -
-           
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-IntrusionException

-
-public IntrusionException()
-
-
Internal classes may throw an IntrusionException to the IntrusionDetector, which generates the appropriate log - message. -

-

-
- -

-IntrusionException

-
-public IntrusionException(java.lang.String userMessage,
-                          java.lang.String logMessage)
-
-
Creates a new instance of IntrusionException. -

-

-
- -

-IntrusionException

-
-public IntrusionException(java.lang.String userMessage,
-                          java.lang.String logMessage,
-                          java.lang.Throwable cause)
-
-
Instantiates a new intrusion exception. -

-

Parameters:
cause - the cause
- - - - - - - - -
-Method Detail
- -

-getUserMessage

-
-public java.lang.String getUserMessage()
-
-
-
-
-
-
- -

-getLogMessage

-
-public java.lang.String getLogMessage()
-
-
-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/JavaLogFactory.html b/javadoc/org/owasp/esapi/JavaLogFactory.html deleted file mode 100644 index 94d1921b5..000000000 --- a/javadoc/org/owasp/esapi/JavaLogFactory.html +++ /dev/null @@ -1,284 +0,0 @@ - - - - - - -JavaLogFactory - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class JavaLogFactory

-
-java.lang.Object
-  extended byorg.owasp.esapi.JavaLogFactory
-
-
-
All Implemented Interfaces:
ILogFactory
-
-
-
-
public class JavaLogFactory
extends java.lang.Object
implements ILogFactory
- -

-

-
Author:
-
rdawes
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
JavaLogFactory(java.lang.String applicationName) - -
-           
-  - - - - - - - - - - - - - - - -
-Method Summary
- ILoggergetLogger(java.lang.Class clazz) - -
-           
- ILoggergetLogger(java.lang.String name) - -
-           
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-JavaLogFactory

-
-public JavaLogFactory(java.lang.String applicationName)
-
-
- - - - - - - - -
-Method Detail
- -

-getLogger

-
-public ILogger getLogger(java.lang.Class clazz)
-
-
-
Specified by:
getLogger in interface ILogFactory
-
-
-
-
-
-
- -

-getLogger

-
-public ILogger getLogger(java.lang.String name)
-
-
-
Specified by:
getLogger in interface ILogFactory
-
-
-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/LogFactory.html b/javadoc/org/owasp/esapi/LogFactory.html deleted file mode 100644 index 4522af100..000000000 --- a/javadoc/org/owasp/esapi/LogFactory.html +++ /dev/null @@ -1,246 +0,0 @@ - - - - - - -LogFactory - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Interface LogFactory

-
-
All Known Implementing Classes:
JavaLogFactory
-
-
-
-
public interface LogFactory
- -

-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. -

- -

-

-
Author:
-
rdawes
-
See Also:
ESAPI
-
- -

- - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- LoggergetLogger(java.lang.Class clazz) - -
-           
- LoggergetLogger(java.lang.String name) - -
-           
-  -

- - - - - - - - - - - - - - -
-Method Detail
- -

-getLogger

-
-public Logger getLogger(java.lang.String name)
-
-
-
-
-
-
- -

-getLogger

-
-public Logger getLogger(java.lang.Class clazz)
-
-
-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/Logger.html b/javadoc/org/owasp/esapi/Logger.html deleted file mode 100644 index 57db0bf83..000000000 --- a/javadoc/org/owasp/esapi/Logger.html +++ /dev/null @@ -1,738 +0,0 @@ - - - - - - -Logger - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Interface Logger

-
-
-
public interface Logger
- -

-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
-
-
- -

- - - - - - - - - - - - - - - - - - - - - - - - - - -
-Field Summary
-static java.lang.StringFUNCTIONALITY - -
-           
-static java.lang.StringPERFORMANCE - -
-           
-static java.lang.StringSECURITY - -
-           
-static java.lang.StringUSABILITY - -
-           
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- voiddebug(java.lang.String type, - java.lang.String message) - -
-          Log debug.
- voiddebug(java.lang.String type, - java.lang.String message, - java.lang.Throwable throwable) - -
-          Log debug.
- voiderror(java.lang.String type, - java.lang.String message) - -
-          Log error.
- voiderror(java.lang.String type, - java.lang.String message, - java.lang.Throwable throwable) - -
-          Log error.
- voidfatal(java.lang.String type, - java.lang.String message) - -
-          Log critical.
- voidfatal(java.lang.String type, - java.lang.String message, - java.lang.Throwable throwable) - -
-          Log critical.
- voidinfo(java.lang.String type, - java.lang.String message) - -
-          Log success.
- voidinfo(java.lang.String type, - java.lang.String message, - java.lang.Throwable throwable) - -
-          Log success.
- booleanisDebugEnabled() - -
-          Allows the caller to determine if messages logged at this level - will be discarded, to avoid performing expensive processing
- booleanisErrorEnabled() - -
-          Allows the caller to determine if messages logged at this level - will be discarded, to avoid performing expensive processing
- booleanisFatalEnabled() - -
-          Allows the caller to determine if messages logged at this level - will be discarded, to avoid performing expensive processing
- booleanisInfoEnabled() - -
-          Allows the caller to determine if messages logged at this level - will be discarded, to avoid performing expensive processing
- booleanisTraceEnabled() - -
-          Allows the caller to determine if messages logged at this level - will be discarded, to avoid performing expensive processing
- booleanisWarningEnabled() - -
-          Allows the caller to determine if messages logged at this level - will be discarded, to avoid performing expensive processing
- voidtrace(java.lang.String type, - java.lang.String message) - -
-          Log trace.
- voidtrace(java.lang.String type, - java.lang.String message, - java.lang.Throwable throwable) - -
-          Log trace.
- voidwarning(java.lang.String type, - java.lang.String message) - -
-          Log warning.
- voidwarning(java.lang.String type, - java.lang.String message, - java.lang.Throwable throwable) - -
-          Log warning.
-  -

- - - - - - - - -
-Field Detail
- -

-SECURITY

-
-public static final java.lang.String SECURITY
-
-
-
See Also:
Constant Field Values
-
-
- -

-USABILITY

-
-public static final java.lang.String USABILITY
-
-
-
See Also:
Constant Field Values
-
-
- -

-PERFORMANCE

-
-public static final java.lang.String PERFORMANCE
-
-
-
See Also:
Constant Field Values
-
-
- -

-FUNCTIONALITY

-
-public static final java.lang.String FUNCTIONALITY
-
-
-
See Also:
Constant Field Values
-
- - - - - - - - - - - -
-Method Detail
- -

-fatal

-
-public void fatal(java.lang.String type,
-                  java.lang.String message)
-
-
Log critical. -

-

-
Parameters:
type - the type of event
message - the message to log to log
-
-
-
- -

-fatal

-
-public void fatal(java.lang.String type,
-                  java.lang.String message,
-                  java.lang.Throwable throwable)
-
-
Log critical. -

-

-
Parameters:
type - the type of event of event
message - the message to log to log
throwable - the exception thrown
-
-
-
- -

-isFatalEnabled

-
-public boolean isFatalEnabled()
-
-
Allows the caller to determine if messages logged at this level - will be discarded, to avoid performing expensive processing -

-

- -
Returns:
true if fatal messages will be output to the log
-
-
-
- -

-debug

-
-public void debug(java.lang.String type,
-                  java.lang.String message)
-
-
Log debug. -

-

-
Parameters:
type - the type of event
message - the message to log
-
-
-
- -

-debug

-
-public void debug(java.lang.String type,
-                  java.lang.String message,
-                  java.lang.Throwable throwable)
-
-
Log debug. -

-

-
Parameters:
type - the type of event
message - the message to log
throwable - the exception thrown
-
-
-
- -

-isDebugEnabled

-
-public boolean isDebugEnabled()
-
-
Allows the caller to determine if messages logged at this level - will be discarded, to avoid performing expensive processing -

-

- -
Returns:
true if debug messages will be output to the log
-
-
-
- -

-error

-
-public void error(java.lang.String type,
-                  java.lang.String message)
-
-
Log error. -

-

-
Parameters:
type - the type of event
message - the message to log
-
-
-
- -

-error

-
-public void error(java.lang.String type,
-                  java.lang.String message,
-                  java.lang.Throwable throwable)
-
-
Log error. -

-

-
Parameters:
type - the type of event
message - the message to log
throwable - the exception thrown
-
-
-
- -

-isErrorEnabled

-
-public boolean isErrorEnabled()
-
-
Allows the caller to determine if messages logged at this level - will be discarded, to avoid performing expensive processing -

-

- -
Returns:
true if error messages will be output to the log
-
-
-
- -

-info

-
-public void info(java.lang.String type,
-                 java.lang.String message)
-
-
Log success. -

-

-
Parameters:
type - the type of event
message - the message to log
-
-
-
- -

-info

-
-public void info(java.lang.String type,
-                 java.lang.String message,
-                 java.lang.Throwable throwable)
-
-
Log success. -

-

-
Parameters:
type - the type of event
message - the message to log
throwable - the exception thrown
-
-
-
- -

-isInfoEnabled

-
-public boolean isInfoEnabled()
-
-
Allows the caller to determine if messages logged at this level - will be discarded, to avoid performing expensive processing -

-

- -
Returns:
true info if messages will be output to the log
-
-
-
- -

-trace

-
-public void trace(java.lang.String type,
-                  java.lang.String message)
-
-
Log trace. -

-

-
Parameters:
type - the type of event
message - the message to log
-
-
-
- -

-trace

-
-public void trace(java.lang.String type,
-                  java.lang.String message,
-                  java.lang.Throwable throwable)
-
-
Log trace. -

-

-
Parameters:
type - the type of event
message - the message to log
throwable - the exception thrown
-
-
-
- -

-isTraceEnabled

-
-public boolean isTraceEnabled()
-
-
Allows the caller to determine if messages logged at this level - will be discarded, to avoid performing expensive processing -

-

- -
Returns:
true if trace messages will be output to the log
-
-
-
- -

-warning

-
-public void warning(java.lang.String type,
-                    java.lang.String message)
-
-
Log warning. -

-

-
Parameters:
type - the type of event
message - the message to log
-
-
-
- -

-warning

-
-public void warning(java.lang.String type,
-                    java.lang.String message,
-                    java.lang.Throwable throwable)
-
-
Log warning. -

-

-
Parameters:
type - the type of event
message - the message to log
throwable - the exception thrown
-
-
-
- -

-isWarningEnabled

-
-public boolean isWarningEnabled()
-
-
Allows the caller to determine if messages logged at this level - will be discarded, to avoid performing expensive processing -

-

- -
Returns:
true if warning messages will be output to the log
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/LoggerTest.html b/javadoc/org/owasp/esapi/LoggerTest.html deleted file mode 100644 index 0bd5fba05..000000000 --- a/javadoc/org/owasp/esapi/LoggerTest.html +++ /dev/null @@ -1,442 +0,0 @@ - - - - - - -LoggerTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class LoggerTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.LoggerTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class LoggerTest
extends junit.framework.TestCase
- -

-The Class LoggerTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
LoggerTest(java.lang.String testName) - -
-          Instantiates a new logger test.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestLogCritical() - -
-          Test of logCritical method, of class org.owasp.esapi.Logger.
- voidtestLogDebug() - -
-          Test of logDebug method, of class org.owasp.esapi.Logger.
- voidtestLogError() - -
-          Test of logError method, of class org.owasp.esapi.Logger.
- voidtestLogHTTPRequest() - -
-          Test of logHTTPRequest method, of class org.owasp.esapi.Logger.
- voidtestLogSuccess() - -
-          Test of logSuccess method, of class org.owasp.esapi.Logger.
- voidtestLogTrace() - -
-          Test of logTrace method, of class org.owasp.esapi.Logger.
- voidtestLogWarning() - -
-          Test of logWarning method, of class org.owasp.esapi.Logger.
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-LoggerTest

-
-public LoggerTest(java.lang.String testName)
-
-
Instantiates a new logger test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testLogHTTPRequest

-
-public void testLogHTTPRequest()
-                        throws ValidationException,
-                               java.io.IOException,
-                               AuthenticationException
-
-
Test of logHTTPRequest method, of class org.owasp.esapi.Logger. -

-

- -
Throws: -
ValidationException - the validation exception -
java.io.IOException - Signals that an I/O exception has occurred. -
AuthenticationException - the authentication exception
-
-
-
- -

-testLogSuccess

-
-public void testLogSuccess()
-
-
Test of logSuccess method, of class org.owasp.esapi.Logger. -

-

-
-
-
-
- -

-testLogTrace

-
-public void testLogTrace()
-
-
Test of logTrace method, of class org.owasp.esapi.Logger. -

-

-
-
-
-
- -

-testLogDebug

-
-public void testLogDebug()
-
-
Test of logDebug method, of class org.owasp.esapi.Logger. -

-

-
-
-
-
- -

-testLogError

-
-public void testLogError()
-
-
Test of logError method, of class org.owasp.esapi.Logger. -

-

-
-
-
-
- -

-testLogWarning

-
-public void testLogWarning()
-
-
Test of logWarning method, of class org.owasp.esapi.Logger. -

-

-
-
-
-
- -

-testLogCritical

-
-public void testLogCritical()
-
-
Test of logCritical method, of class org.owasp.esapi.Logger. -

-

-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/RandomAccessReferenceMap.html b/javadoc/org/owasp/esapi/RandomAccessReferenceMap.html deleted file mode 100644 index 416d8460d..000000000 --- a/javadoc/org/owasp/esapi/RandomAccessReferenceMap.html +++ /dev/null @@ -1,444 +0,0 @@ - - - - - - -RandomAccessReferenceMap - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class RandomAccessReferenceMap

-
-java.lang.Object
-  extended byorg.owasp.esapi.RandomAccessReferenceMap
-
-
-
All Implemented Interfaces:
AccessReferenceMap
-
-
-
-
public class RandomAccessReferenceMap
extends java.lang.Object
implements AccessReferenceMap
- -

-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. -

- -

-

-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
AccessReferenceMap
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
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.StringaddDirectReference(java.lang.Object direct) - -
-          Adds a direct reference and a new random indirect reference, overwriting any existing values.
- java.lang.ObjectgetDirectReference(java.lang.String indirectReference) - -
-          Get the original direct object reference from an indirect reference.
- java.lang.StringgetIndirectReference(java.lang.Object directReference) - -
-          Get a safe indirect reference to use in place of a potentially sensitive - direct object reference.
- java.util.Iteratoriterator() - -
-          Get an iterator through the direct object references.
- java.lang.StringremoveDirectReference(java.lang.Object direct) - -
-          Remove a direct reference and the corresponding indirect reference.
- voidupdate(java.util.Set directReferences) - -
-          This preserves any existing mappings for items that are still in the new - list.
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-RandomAccessReferenceMap

-
-public RandomAccessReferenceMap()
-
-
This AccessReferenceMap implementation uses short random strings to - create a layer of indirection. Other possible implementations would use - simple integers as indirect references. -

-

-
- -

-RandomAccessReferenceMap

-
-public RandomAccessReferenceMap(java.util.Set directReferences)
-
-
Instantiates a new access reference map. -

-

Parameters:
directReferences - the direct references
- - - - - - - - -
-Method Detail
- -

-iterator

-
-public java.util.Iterator iterator()
-
-
Description copied from interface: AccessReferenceMap
-
Get an iterator through the direct object references. No guarantee is made as - to the order of items returned. -

-

-
Specified by:
iterator in interface AccessReferenceMap
-
-
- -
Returns:
the iterator
-
-
-
- -

-addDirectReference

-
-public java.lang.String addDirectReference(java.lang.Object direct)
-
-
Adds a direct reference and a new random indirect reference, overwriting any existing values. -

-

-
Specified by:
addDirectReference in interface AccessReferenceMap
-
-
-
Parameters:
direct - -
Returns:
the corresponding indirect reference
-
-
-
- -

-removeDirectReference

-
-public java.lang.String removeDirectReference(java.lang.Object direct)
-                                       throws AccessControlException
-
-
Remove a direct reference and the corresponding indirect reference. -

-

-
Specified by:
removeDirectReference in interface AccessReferenceMap
-
-
-
Parameters:
direct - -
Returns:
the corresponding indirect reference -
Throws: -
AccessControlException - FIXME Why might we throw an ACE here?
-
-
-
- -

-update

-
-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. -

-

-
-
-
-
Parameters:
directReferences - the direct references
-
-
-
- -

-getIndirectReference

-
-public java.lang.String getIndirectReference(java.lang.Object directReference)
-
-
Description copied from interface: AccessReferenceMap
-
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. -

-

-
Specified by:
getIndirectReference in interface AccessReferenceMap
-
-
-
Parameters:
directReference - the direct reference -
Returns:
the indirect reference
-
-
-
- -

-getDirectReference

-
-public java.lang.Object getDirectReference(java.lang.String indirectReference)
-                                    throws AccessControlException
-
-
Description copied from interface: AccessReferenceMap
-
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. -

-

-
Specified by:
getDirectReference in interface AccessReferenceMap
-
-
-
Parameters:
indirectReference - the indirect reference -
Returns:
the direct reference -
Throws: -
AccessControlException - if no direct reference exists for the - specified indirect reference
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/Randomizer.html b/javadoc/org/owasp/esapi/Randomizer.html deleted file mode 100644 index aac181cdd..000000000 --- a/javadoc/org/owasp/esapi/Randomizer.html +++ /dev/null @@ -1,377 +0,0 @@ - - - - - - -Randomizer - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Interface Randomizer

-
-
All Known Implementing Classes:
DefaultRandomizer
-
-
-
-
public interface Randomizer
- -

-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
-
-
- -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- booleangetRandomBoolean() - -
-          Returns a random boolean.
- java.lang.StringgetRandomFilename(java.lang.String extension) - -
-          Returns an unguessable random filename with the specified extension.
- java.lang.StringgetRandomGUID() - -
-          Generates a random GUID.
- intgetRandomInteger(int min, - int max) - -
-          Gets the random integer.
- longgetRandomLong() - -
-          Gets the random long.
- floatgetRandomReal(float min, - float max) - -
-          Gets the random real.
- java.lang.StringgetRandomString(int length, - char[] characterSet) - -
-          Gets a random string.
-  -

- - - - - - - - - - - - - - -
-Method Detail
- -

-getRandomString

-
-public java.lang.String getRandomString(int length,
-                                        char[] characterSet)
-
-
Gets a random string. of a desired length and character set. -

-

-
Parameters:
length - the length of the string
characterSet - the character set -
Returns:
the random string
-
-
-
- -

-getRandomBoolean

-
-public boolean getRandomBoolean()
-
-
Returns a random boolean. -

-

- -
Returns:
true or false, randomly
-
-
-
- -

-getRandomInteger

-
-public int getRandomInteger(int min,
-                            int max)
-
-
Gets the random integer. -

-

-
Parameters:
min - the minimum integer that will be returned
max - the maximum integer that will be returned -
Returns:
the random integer
-
-
-
- -

-getRandomLong

-
-public long getRandomLong()
-
-
Gets the random long. -

-

- -
Returns:
the random long
-
-
-
- -

-getRandomFilename

-
-public java.lang.String getRandomFilename(java.lang.String extension)
-
-
Returns an unguessable random filename with the specified extension. -

-

- -
Returns:
a random unguessable filename ending with the specified extension
-
-
-
- -

-getRandomReal

-
-public float getRandomReal(float min,
-                           float max)
-
-
Gets the random real. -

-

-
Parameters:
min - the minimum real number that will be returned
max - the maximum real number that will be returned -
Returns:
the random real
-
-
-
- -

-getRandomGUID

-
-public java.lang.String getRandomGUID()
-                               throws EncryptionException
-
-
Generates a random GUID. -

-

- -
Returns:
the GUID -
Throws: -
EncryptionException
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/RandomizerTest.html b/javadoc/org/owasp/esapi/RandomizerTest.html deleted file mode 100644 index 6d0276bb8..000000000 --- a/javadoc/org/owasp/esapi/RandomizerTest.html +++ /dev/null @@ -1,375 +0,0 @@ - - - - - - -RandomizerTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class RandomizerTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.RandomizerTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class RandomizerTest
extends junit.framework.TestCase
- -

-The Class RandomizerTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
RandomizerTest(java.lang.String testName) - -
-          Instantiates a new randomizer test.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestGetRandomGUID() - -
-          Test of getRandomGUID method, of class org.owasp.esapi.Randomizer.
- voidtestGetRandomInteger() - -
-          Test of getRandomInteger method, of class org.owasp.esapi.Randomizer.
- voidtestGetRandomReal() - -
-          Test of getRandomReal method, of class org.owasp.esapi.Randomizer.
- voidtestGetRandomString() - -
-          Test of getRandomString method, of class org.owasp.esapi.Randomizer.
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-RandomizerTest

-
-public RandomizerTest(java.lang.String testName)
-
-
Instantiates a new randomizer test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testGetRandomString

-
-public void testGetRandomString()
-
-
Test of getRandomString method, of class org.owasp.esapi.Randomizer. -

-

-
-
-
-
- -

-testGetRandomInteger

-
-public void testGetRandomInteger()
-
-
Test of getRandomInteger method, of class org.owasp.esapi.Randomizer. -

-

-
-
-
-
- -

-testGetRandomReal

-
-public void testGetRandomReal()
-
-
Test of getRandomReal method, of class org.owasp.esapi.Randomizer. -

-

-
-
-
-
- -

-testGetRandomGUID

-
-public void testGetRandomGUID()
-                       throws EncryptionException
-
-
Test of getRandomGUID method, of class org.owasp.esapi.Randomizer. -

-

- -
Throws: -
EncryptionException
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/SafeFile.html b/javadoc/org/owasp/esapi/SafeFile.html deleted file mode 100644 index ecc7ec3b2..000000000 --- a/javadoc/org/owasp/esapi/SafeFile.html +++ /dev/null @@ -1,308 +0,0 @@ - - - - - - -SafeFile - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class SafeFile

-
-java.lang.Object
-  extended byjava.io.File
-      extended byorg.owasp.esapi.SafeFile
-
-
-
All Implemented Interfaces:
java.lang.Comparable, java.io.Serializable
-
-
-
-
public class SafeFile
extends java.io.File
- -

-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. -

- -

-

-
See Also:
Serialized Form
-
- -

- - - - - - - - - - -
-Field Summary
- - - - - - - -
Fields inherited from class java.io.File
pathSeparator, pathSeparatorChar, separator, separatorChar
-  - - - - - - - - - - - - - - - - - - - -
-Constructor Summary
SafeFile(java.io.File parent, - java.lang.String child) - -
-           
SafeFile(java.lang.String path) - -
-           
SafeFile(java.lang.String parent, - java.lang.String child) - -
-           
SafeFile(java.net.URI uri) - -
-           
-  - - - - - - - - - - -
Methods inherited from class java.io.File
canRead, canWrite, compareTo, compareTo, createNewFile, createTempFile, createTempFile, delete, deleteOnExit, equals, exists, getAbsoluteFile, getAbsolutePath, getCanonicalFile, getCanonicalPath, getName, getParent, getParentFile, getPath, hashCode, isAbsolute, isDirectory, isFile, isHidden, lastModified, length, list, list, listFiles, listFiles, listFiles, listRoots, mkdir, mkdirs, renameTo, setLastModified, setReadOnly, toString, toURI, toURL
- - - - - - - -
Methods inherited from class java.lang.Object
getClass, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-SafeFile

-
-public SafeFile(java.lang.String path)
-         throws ValidationException
-
-
-
- -

-SafeFile

-
-public SafeFile(java.lang.String parent,
-                java.lang.String child)
-         throws ValidationException
-
-
-
- -

-SafeFile

-
-public SafeFile(java.io.File parent,
-                java.lang.String child)
-         throws ValidationException
-
-
-
- -

-SafeFile

-
-public SafeFile(java.net.URI uri)
-         throws ValidationException
-
-
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/SafeFileTest.html b/javadoc/org/owasp/esapi/SafeFileTest.html deleted file mode 100644 index 43a7b55ef..000000000 --- a/javadoc/org/owasp/esapi/SafeFileTest.html +++ /dev/null @@ -1,495 +0,0 @@ - - - - - - -SafeFileTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class SafeFileTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.SafeFileTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class SafeFileTest
extends junit.framework.TestCase
- -

-The Class ExecutorTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
SafeFileTest(java.lang.String testName) - -
-          Instantiates a new executor test.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestAlternateDataStream() - -
-           
- voidtestCreateSafeFile() - -
-          Test of executeOSCommand method, of class org.owasp.esapi.Executor
- voidtestCreateSafeFileParentConstructor() - -
-           
- voidtestCreateSafeFileURIConstructor() - -
-           
- voidtestJavaDirInjection() - -
-           
- voidtestJavaFileInjection() - -
-           
- voidtestMultipleJavaFileInjection() - -
-           
- voidtestNormalPercentEncodedFileInjection() - -
-           
- voidtestWeirdPercentEncodedFileInjection() - -
-           
-static java.lang.StringtoHex(byte b) - -
-           
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-SafeFileTest

-
-public SafeFileTest(java.lang.String testName)
-
-
Instantiates a new executor test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testJavaFileInjection

-
-public void testJavaFileInjection()
-
-
-
-
-
-
- -

-testMultipleJavaFileInjection

-
-public void testMultipleJavaFileInjection()
-
-
-
-
-
-
- -

-testAlternateDataStream

-
-public void testAlternateDataStream()
-
-
-
-
-
-
- -

-testJavaDirInjection

-
-public void testJavaDirInjection()
-
-
-
-
-
-
- -

-toHex

-
-public static java.lang.String toHex(byte b)
-
-
-
-
-
-
- -

-testNormalPercentEncodedFileInjection

-
-public void testNormalPercentEncodedFileInjection()
-                                           throws java.lang.Exception
-
-
- -
Throws: -
java.lang.Exception
-
-
-
- -

-testWeirdPercentEncodedFileInjection

-
-public void testWeirdPercentEncodedFileInjection()
-                                          throws java.lang.Exception
-
-
- -
Throws: -
java.lang.Exception
-
-
-
- -

-testCreateSafeFile

-
-public void testCreateSafeFile()
-                        throws java.lang.Exception
-
-
Test of executeOSCommand method, of class org.owasp.esapi.Executor -

-

- -
Throws: -
java.lang.Exception - the exception
-
-
-
- -

-testCreateSafeFileParentConstructor

-
-public void testCreateSafeFileParentConstructor()
-                                         throws java.lang.Exception
-
-
- -
Throws: -
java.lang.Exception
-
-
-
- -

-testCreateSafeFileURIConstructor

-
-public void testCreateSafeFileURIConstructor()
-                                      throws java.lang.Exception
-
-
- -
Throws: -
java.lang.Exception
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/SecurityConfiguration.Threshold.html b/javadoc/org/owasp/esapi/SecurityConfiguration.Threshold.html deleted file mode 100644 index 536508ca7..000000000 --- a/javadoc/org/owasp/esapi/SecurityConfiguration.Threshold.html +++ /dev/null @@ -1,318 +0,0 @@ - - - - - - -SecurityConfiguration.Threshold - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class SecurityConfiguration.Threshold

-
-java.lang.Object
-  extended byorg.owasp.esapi.SecurityConfiguration.Threshold
-
-
-
Enclosing class:
SecurityConfiguration
-
-
-
-
public static class SecurityConfiguration.Threshold
extends java.lang.Object
- -

-Models a simple threshold as a count and an interval, along with a set of actions to take if the threshold is exceeded. -

- -

-


- -

- - - - - - - - - - - - - - - - - - - - - - - - - - -
-Field Summary
- java.util.Listactions - -
-           
- intcount - -
-           
- longinterval - -
-           
- java.lang.Stringname - -
-           
-  - - - - - - - - - - -
-Constructor Summary
SecurityConfiguration.Threshold(java.lang.String name, - int count, - long interval, - java.util.List actions) - -
-           
-  - - - - - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - -
-Field Detail
- -

-name

-
-public java.lang.String name
-
-
-
-
-
- -

-count

-
-public int count
-
-
-
-
-
- -

-interval

-
-public long interval
-
-
-
-
-
- -

-actions

-
-public java.util.List actions
-
-
-
-
- - - - - - - - -
-Constructor Detail
- -

-SecurityConfiguration.Threshold

-
-public SecurityConfiguration.Threshold(java.lang.String name,
-                                       int count,
-                                       long interval,
-                                       java.util.List actions)
-
-
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/SecurityConfiguration.html b/javadoc/org/owasp/esapi/SecurityConfiguration.html deleted file mode 100644 index fdd8f3302..000000000 --- a/javadoc/org/owasp/esapi/SecurityConfiguration.html +++ /dev/null @@ -1,691 +0,0 @@ - - - - - - -SecurityConfiguration - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Interface SecurityConfiguration

-
-
All Known Implementing Classes:
DefaultSecurityConfiguration
-
-
-
-
public interface SecurityConfiguration
- -

-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 classSecurityConfiguration.Threshold - -
-          Models a simple threshold as a count and an interval, along with a set of actions to take if the threshold is exceeded.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- java.util.ListgetAllowedFileExtensions() - -
-          Gets the allowed file extensions.
- intgetAllowedFileUploadSize() - -
-          Gets the allowed file upload size.
- intgetAllowedLoginAttempts() - -
-          Gets the allowed login attempts.
- java.lang.StringgetApplicationName() - -
-          Gets the application name, used for logging
- java.lang.StringgetCharacterEncoding() - -
-          Gets the character encoding.
- java.lang.StringgetDigitalSignatureAlgorithm() - -
-          Gets the digital signature algorithm.
- java.lang.StringgetEncryptionAlgorithm() - -
-          Gets the encryption algorithm.
- java.lang.StringgetHashAlgorithm() - -
-          Gets the hashing algorithm.
- java.io.FilegetKeystore() - -
-          Gets the keystore.
- booleangetLogEncodingRequired() - -
-          Returns whether HTML entity encoding should be applied to log entries.
- char[]getMasterPassword() - -
-          Gets the master password.
- byte[]getMasterSalt() - -
-          Gets the master salt.
- intgetMaxOldPasswordHashes() - -
-          Gets the max old password hashes.
- java.lang.StringgetPasswordParameterName() - -
-          Gets the password parameter name.
- SecurityConfiguration.ThresholdgetQuota(java.lang.String eventName) - -
-          Gets an intrusion detection Quota.
- java.lang.StringgetRandomAlgorithm() - -
-          Gets the random number generation algorithm.
- longgetRememberTokenDuration() - -
-          Gets the time window allowed for the remember token in milliseconds.
- java.lang.StringgetResourceDirectory() - -
-          Gets the ESAPI resource directory as a String.
- java.lang.StringgetResponseContentType() - -
-          Gets the content-type set for responses.
- java.lang.StringgetUsernameParameterName() - -
-          Gets the username parameter name.
- voidsetResourceDirectory(java.lang.String dir) - -
-          Sets the ESAPI resource directory.
-  -

- - - - - - - - - - - - - - -
-Method Detail
- -

-getApplicationName

-
-public java.lang.String getApplicationName()
-
-
Gets the application name, used for logging -

-

- -
Returns:
the application name
-
-
-
- -

-getMasterPassword

-
-public char[] getMasterPassword()
-
-
Gets the master password. -

-

- -
Returns:
the master password
-
-
-
- -

-getKeystore

-
-public java.io.File getKeystore()
-
-
Gets the keystore. -

-

- -
Returns:
the keystore
-
-
-
- -

-getMasterSalt

-
-public byte[] getMasterSalt()
-
-
Gets the master salt. -

-

- -
Returns:
the master salt
-
-
-
- -

-getAllowedFileExtensions

-
-public java.util.List getAllowedFileExtensions()
-
-
Gets the allowed file extensions. -

-

- -
Returns:
the allowed file extensions
-
-
-
- -

-getAllowedFileUploadSize

-
-public int getAllowedFileUploadSize()
-
-
Gets the allowed file upload size. -

-

- -
Returns:
the allowed file upload size
-
-
-
- -

-getPasswordParameterName

-
-public java.lang.String getPasswordParameterName()
-
-
Gets the password parameter name. -

-

- -
Returns:
the password parameter name
-
-
-
- -

-getUsernameParameterName

-
-public java.lang.String getUsernameParameterName()
-
-
Gets the username parameter name. -

-

- -
Returns:
the username parameter name
-
-
-
- -

-getEncryptionAlgorithm

-
-public java.lang.String getEncryptionAlgorithm()
-
-
Gets the encryption algorithm. -

-

- -
Returns:
the encryption algorithm
-
-
-
- -

-getHashAlgorithm

-
-public java.lang.String getHashAlgorithm()
-
-
Gets the hashing algorithm. -

-

- -
Returns:
the hashing algorithm
-
-
-
- -

-getCharacterEncoding

-
-public java.lang.String getCharacterEncoding()
-
-
Gets the character encoding. -

-

- -
Returns:
encoding character name
-
-
-
- -

-getDigitalSignatureAlgorithm

-
-public java.lang.String getDigitalSignatureAlgorithm()
-
-
Gets the digital signature algorithm. -

-

- -
Returns:
the digital signature algorithm
-
-
-
- -

-getRandomAlgorithm

-
-public java.lang.String getRandomAlgorithm()
-
-
Gets the random number generation algorithm. -

-

- -
Returns:
random number generation algorithm
-
-
-
- -

-getAllowedLoginAttempts

-
-public int getAllowedLoginAttempts()
-
-
Gets the allowed login attempts. -

-

- -
Returns:
the allowed login attempts
-
-
-
- -

-getMaxOldPasswordHashes

-
-public int getMaxOldPasswordHashes()
-
-
Gets the max old password hashes. -

-

- -
Returns:
the max old password hashes
-
-
-
- -

-getQuota

-
-public SecurityConfiguration.Threshold getQuota(java.lang.String eventName)
-
-
Gets an intrusion detection Quota. -

-

-
Parameters:
eventName - the event whose quota is desired -
Returns:
the matching Quota for eventName
-
-
-
- -

-getResourceDirectory

-
-public java.lang.String getResourceDirectory()
-
-
Gets the ESAPI resource directory as a String. -

-

- -
Returns:
the ESAPI resource directory
-
-
-
- -

-setResourceDirectory

-
-public void setResourceDirectory(java.lang.String dir)
-
-
Sets the ESAPI resource directory. -

-

-
Parameters:
dir - location of the resource directory
-
-
-
- -

-getResponseContentType

-
-public java.lang.String getResponseContentType()
-
-
Gets the content-type set for responses. -

-

-
-
-
-
- -

-getRememberTokenDuration

-
-public long getRememberTokenDuration()
-
-
Gets the time window allowed for the remember token in milliseconds. -

-

-
-
-
-
- -

-getLogEncodingRequired

-
-public boolean getLogEncodingRequired()
-
-
Returns whether HTML entity encoding should be applied to log entries. -

-

-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/StringUtilities.html b/javadoc/org/owasp/esapi/StringUtilities.html deleted file mode 100644 index 4400cc26c..000000000 --- a/javadoc/org/owasp/esapi/StringUtilities.html +++ /dev/null @@ -1,315 +0,0 @@ - - - - - - -StringUtilities - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class StringUtilities

-
-java.lang.Object
-  extended byorg.owasp.esapi.StringUtilities
-
-
-
-
public class StringUtilities
extends java.lang.Object
- -

-String utilities used in various filters. -

- -

-

-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
StringUtilities() - -
-           
-  - - - - - - - - - - - - - - - - - - - -
-Method Summary
-static booleancontains(java.lang.StringBuffer haystack, - char c) - -
-          Returns true if the character is contained in the provided StringBuffer.
-static java.lang.StringstripControls(java.lang.String input) - -
-          Removes all unprintable characters from a string - and replaces with a space for use in an HTTP header
-static char[]union(char[] c1, - char[] c2) - -
-          Union two character arrays.
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-StringUtilities

-
-public StringUtilities()
-
-
- - - - - - - - -
-Method Detail
- -

-stripControls

-
-public static java.lang.String stripControls(java.lang.String input)
-
-
Removes all unprintable characters from a string - and replaces with a space for use in an HTTP header -

-

-
Parameters:
input - -
Returns:
the stripped header
-
-
-
- -

-union

-
-public static char[] union(char[] c1,
-                           char[] c2)
-
-
Union two character arrays. -

-

-
Parameters:
c1 - the c1
c2 - the c2 -
Returns:
the char[]
-
-
-
- -

-contains

-
-public static boolean contains(java.lang.StringBuffer haystack,
-                               char c)
-
-
Returns true if the character is contained in the provided StringBuffer. -

-

-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/Threshold.html b/javadoc/org/owasp/esapi/Threshold.html deleted file mode 100644 index e3eff7980..000000000 --- a/javadoc/org/owasp/esapi/Threshold.html +++ /dev/null @@ -1,322 +0,0 @@ - - - - - - -Threshold - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class Threshold

-
-java.lang.Object
-  extended byorg.owasp.esapi.Threshold
-
-
-
-
public class Threshold
extends java.lang.Object
- -

-The threshold class simply models the data for a basic threshold with a name, - elapsed time, counter, and a set of actions to take. -

- -

-

-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com) Aspect Security
-
-
- -

- - - - - - - - - - - - - - - - - - - - - - - - - - -
-Field Summary
- java.util.Listactions - -
-           
- intcount - -
-           
- longinterval - -
-           
- java.lang.Stringname - -
-           
-  - - - - - - - - - - -
-Constructor Summary
Threshold(java.lang.String name, - int count, - long interval, - java.util.List actions) - -
-           
-  - - - - - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - -
-Field Detail
- -

-name

-
-public java.lang.String name
-
-
-
-
-
- -

-count

-
-public int count
-
-
-
-
-
- -

-interval

-
-public long interval
-
-
-
-
-
- -

-actions

-
-public java.util.List actions
-
-
-
-
- - - - - - - - -
-Constructor Detail
- -

-Threshold

-
-public Threshold(java.lang.String name,
-                 int count,
-                 long interval,
-                 java.util.List actions)
-
-
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/User.html b/javadoc/org/owasp/esapi/User.html deleted file mode 100644 index 930d42360..000000000 --- a/javadoc/org/owasp/esapi/User.html +++ /dev/null @@ -1,1295 +0,0 @@ - - - - - - -User - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Interface User

-
-
All Superinterfaces:
java.security.Principal
-
-
-
All Known Implementing Classes:
DefaultUser
-
-
-
-
public interface User
extends java.security.Principal
- -

-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. -

- -

-

-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams at Aspect Security
-
-
- -

- - - - - - - - - - - - - - -
-Field Summary
-static UserANONYMOUS - -
-          The ANONYMOUS user is used to represent an unidentified user.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- voidaddRole(java.lang.String role) - -
-          Adds a role to an account.
- voidaddRoles(java.util.Set newRoles) - -
-          Adds a set of roles to an account.
- voidchangePassword(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.
- voiddisable() - -
-          Disable account.
- voidenable() - -
-          Enable account.
- longgetAccountId() - -
-          Gets the account id.
- java.lang.StringgetAccountName() - -
-          Gets the account name.
- java.lang.StringgetCSRFToken() - -
-          Gets the CSRF token.
- java.util.DategetExpirationTime() - -
-          Returns the date that the current user's account will expire, usually when the account will be disabled.
- intgetFailedLoginCount() - -
-          Returns the number of failed login attempts since the last successful login for an account.
- java.util.DategetLastFailedLoginTime() - -
-          Returns the date of the last failed login time for a user.
- java.lang.StringgetLastHostAddress() - -
-          Returns the last host address used by the user.
- java.util.DategetLastLoginTime() - -
-          Returns the date of the last successful login time for a user.
- java.util.DategetLastPasswordChangeTime() - -
-          Gets the date of user's last password change.
- java.util.SetgetRoles() - -
-          Gets the roles assigned to a particular account.
- java.lang.StringgetScreenName() - -
-          Gets the screen name.
- voidincrementFailedLoginCount() - -
-          Increment failed login count.
- booleanisAnonymous() - -
-          Checks if user is anonymous.
- booleanisEnabled() - -
-          Checks if an account is currently enabled.
- booleanisExpired() - -
-          Checks if an account is expired.
- booleanisInRole(java.lang.String role) - -
-          Checks if an account has been assigned a particular role.
- booleanisLocked() - -
-          Checks if an account is locked.
- booleanisLoggedIn() - -
-          Tests to see if the user is currently logged in.
- booleanisSessionAbsoluteTimeout() - -
-          Tests to see if the user's session has exceeded the absolute time out.
- booleanisSessionTimeout() - -
-          Tests to see if the user's session has timed out from inactivity.
- voidlock() - -
-          Lock the user's account.
- voidloginWithPassword(java.lang.String password) - -
-          Login with password.
- voidlogout() - -
-          Logout this user.
- voidremoveRole(java.lang.String role) - -
-          Removes a role from an account.
- java.lang.StringresetCSRFToken() - -
-          Returns a token to be used as a prevention against CSRF attacks.
- voidsetAccountName(java.lang.String accountName) - -
-          Sets the account name.
- voidsetExpirationTime(java.util.Date expirationTime) - -
-          Sets the time when this user's account will expire.
- voidsetLastFailedLoginTime(java.util.Date lastFailedLoginTime) - -
-          Set the time of the last failed login for this user.
- voidsetLastHostAddress(java.lang.String remoteHost) - -
-          Set the last remote host address used by this user.
- voidsetLastLoginTime(java.util.Date lastLoginTime) - -
-          Set the time of the last successful login for this user.
- voidsetLastPasswordChangeTime(java.util.Date lastPasswordChangeTime) - -
-          Set the time of the last password change for this user.
- voidsetRoles(java.util.Set roles) - -
-          Sets the roles of this account.
- voidsetScreenName(java.lang.String screenName) - -
-          Sets the screen name.
- voidunlock() - -
-          Unlock account.
- booleanverifyPassword(java.lang.String password) - -
-          Verify that the supplied password matches the password for this user.
- - - - - - - -
Methods inherited from interface java.security.Principal
equals, getName, hashCode, toString
-  -

- - - - - - - - -
-Field Detail
- -

-ANONYMOUS

-
-public static final User ANONYMOUS
-
-
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. -

-

-
-
- - - - - - - - - - - -
-Method Detail
- -

-addRole

-
-public void addRole(java.lang.String role)
-             throws AuthenticationException
-
-
Adds a role to an account. -

-

-
-
-
-
Parameters:
role - the role to add -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-addRoles

-
-public void addRoles(java.util.Set newRoles)
-              throws AuthenticationException
-
-
Adds a set of roles to an account. -

-

-
-
-
-
Parameters:
newRoles - the new roles to add -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-changePassword

-
-public void changePassword(java.lang.String oldPassword,
-                           java.lang.String newPassword1,
-                           java.lang.String newPassword2)
-                    throws AuthenticationException,
-                           EncryptionException
-
-
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 -
EncryptionException
-
-
-
- -

-disable

-
-public void disable()
-
-
Disable account. -

-

-
-
-
- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-enable

-
-public void enable()
-
-
Enable account. -

-

-
-
-
- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-getAccountId

-
-public long getAccountId()
-
-
Gets the account id. -

-

-
-
-
- -
Returns:
the account id
-
-
-
- -

-getAccountName

-
-public java.lang.String getAccountName()
-
-
Gets the account name. -

-

-
-
-
- -
Returns:
the account name
-
-
-
- -

-getCSRFToken

-
-public java.lang.String getCSRFToken()
-
-
Gets the CSRF token. -

-

-
-
-
- -
Returns:
the CSRF token
-
-
-
- -

-getExpirationTime

-
-public java.util.Date getExpirationTime()
-
-
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 last host address used by the user
-
-
-
- -

-getLastFailedLoginTime

-
-public java.util.Date getLastFailedLoginTime()
-                                      throws AuthenticationException
-
-
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:
date of the last failed login -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-getLastLoginTime

-
-public java.util.Date getLastLoginTime()
-
-
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:
date of the last successful login
-
-
-
- -

-getLastPasswordChangeTime

-
-public java.util.Date getLastPasswordChangeTime()
-
-
Gets the date of user's last password change. -

-

-
-
-
- -
Returns:
the date of last password change
-
-
-
- -

-getRoles

-
-public java.util.Set getRoles()
-
-
Gets the roles assigned to a particular account. -

-

-
-
-
- -
Returns:
an immutable set of roles
-
-
-
- -

-getScreenName

-
-public java.lang.String getScreenName()
-
-
Gets the screen name. -

-

-
-
-
- -
Returns:
the screen name
-
-
-
- -

-incrementFailedLoginCount

-
-public void incrementFailedLoginCount()
-
-
Increment failed login count. -

-

-
-
-
-
-
-
-
- -

-isAnonymous

-
-public boolean isAnonymous()
-
-
Checks if user is anonymous. -

-

-
-
-
- -
Returns:
true, if user is anonymous
-
-
-
- -

-isEnabled

-
-public boolean isEnabled()
-
-
Checks if an account is currently enabled. -

-

-
-
-
- -
Returns:
true, if account is enabled
-
-
-
- -

-isExpired

-
-public boolean isExpired()
-
-
Checks if an account is expired. -

-

-
-
-
- -
Returns:
true, if account is expired
-
-
-
- -

-isInRole

-
-public boolean isInRole(java.lang.String role)
-
-
Checks if an account has been assigned a particular role. -

-

-
-
-
-
Parameters:
role - the role for which to check -
Returns:
true, if role has been assigned to user
-
-
-
- -

-isLocked

-
-public boolean isLocked()
-
-
Checks if an account is locked. -

-

-
-
-
- -
Returns:
true, if account is locked
-
-
-
- -

-isLoggedIn

-
-public boolean isLoggedIn()
-
-
Tests to see if the user is currently logged in. -

-

-
-
-
- -
Returns:
true, if the user is logged in
-
-
-
- -

-isSessionAbsoluteTimeout

-
-public boolean isSessionAbsoluteTimeout()
-
-
Tests to see if the user's session has exceeded the absolute time out. -

-

-
-
-
- -
Returns:
true, if user's session has exceeded the absolute time out
-
-
-
- -

-isSessionTimeout

-
-public boolean isSessionTimeout()
-
-
Tests to see if the user's session has timed out from inactivity. -

-

-
-
-
- -
Returns:
true, if user's session has timed out from inactivity
-
-
-
- -

-lock

-
-public void lock()
-
-
Lock the user's account. -

-

-
-
-
-
-
-
-
- -

-loginWithPassword

-
-public void loginWithPassword(java.lang.String password)
-                       throws AuthenticationException
-
-
Login with password. -

-

-
-
-
-
Parameters:
password - the password -
Throws: -
AuthenticationException - if login fails
-
-
-
- -

-logout

-
-public void logout()
-
-
Logout this user. -

-

-
-
-
-
-
-
-
- -

-removeRole

-
-public void removeRole(java.lang.String role)
-                throws AuthenticationException
-
-
Removes a role from an account. -

-

-
-
-
-
Parameters:
role - the role to remove -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-resetCSRFToken

-
-public java.lang.String resetCSRFToken()
-                                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. -

-

-
-
-
- -
Returns:
the new CSRF token -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-setAccountName

-
-public void setAccountName(java.lang.String accountName)
-
-
Sets the account name. -

-

-
-
-
-
Parameters:
accountName - the new account name
-
-
-
- -

-setExpirationTime

-
-public void setExpirationTime(java.util.Date expirationTime)
-
-
Sets the time when this user's account will expire. -

-

-
-
-
-
Parameters:
expirationTime - the new expiration time
-
-
-
- -

-setRoles

-
-public void setRoles(java.util.Set roles)
-              throws AuthenticationException
-
-
Sets the roles of this account. -

-

-
-
-
-
Parameters:
roles - the new roles -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-setScreenName

-
-public void setScreenName(java.lang.String screenName)
-
-
Sets the screen name. -

-

-
-
-
-
Parameters:
screenName - the new screen name
-
-
-
- -

-unlock

-
-public void unlock()
-
-
Unlock account. -

-

-
-
-
-
-
-
-
- -

-verifyPassword

-
-public boolean verifyPassword(java.lang.String password)
-                       throws EncryptionException
-
-
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 -
Throws: -
EncryptionException
-
-
-
- -

-setLastFailedLoginTime

-
-public void setLastFailedLoginTime(java.util.Date lastFailedLoginTime)
-
-
Set the time of the last failed login for this user. -

-

-
-
-
-
Parameters:
lastFailedLoginTime -
-
-
-
- -

-setLastHostAddress

-
-public void setLastHostAddress(java.lang.String remoteHost)
-
-
Set the last remote host address used by this user. -

-

-
-
-
-
Parameters:
remoteHost -
-
-
-
- -

-setLastLoginTime

-
-public void setLastLoginTime(java.util.Date lastLoginTime)
-
-
Set the time of the last successful login for this user. -

-

-
-
-
-
Parameters:
lastLoginTime -
-
-
-
- -

-setLastPasswordChangeTime

-
-public void setLastPasswordChangeTime(java.util.Date lastPasswordChangeTime)
-
-
Set the time of the last password change for this user. -

-

-
-
-
-
Parameters:
lastPasswordChangeTime -
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/UserTest.html b/javadoc/org/owasp/esapi/UserTest.html deleted file mode 100644 index 72ce0caf3..000000000 --- a/javadoc/org/owasp/esapi/UserTest.html +++ /dev/null @@ -1,1040 +0,0 @@ - - - - - - -UserTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class UserTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.UserTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class UserTest
extends junit.framework.TestCase
- -

-The Class UserTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
UserTest(java.lang.String testName) - -
-          Instantiates a new user test.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestAddRole() - -
-          Test of testAddRole method, of class org.owasp.esapi.User.
- voidtestAddRoles() - -
-          Test of addRoles method, of class org.owasp.esapi.User.
- voidtestChangePassword() - -
-          Test of changePassword method, of class org.owasp.esapi.User.
- voidtestDisable() - -
-          Test of disable method, of class org.owasp.esapi.User.
- voidtestEnable() - -
-          Test of enable method, of class org.owasp.esapi.User.
- voidtestEquals() - -
-          Test equals.
- voidtestFailedLoginLockout() - -
-          Test of failedLoginCount lockout, of class org.owasp.esapi.User.
- voidtestGetAccountName() - -
-          Test of getAccountName method, of class org.owasp.esapi.User.
- voidtestGetLastFailedLoginTime() - -
-          Test get last failed login time.
- voidtestGetLastLoginTime() - -
-          Test get last login time.
- voidtestGetLastPasswordChangeTime() - -
-          Test of getLastPasswordChangeTime method, of class org.owasp.esapi.User.
- voidtestGetRoles() - -
-          Test of getRoles method, of class org.owasp.esapi.User.
- voidtestGetScreenName() - -
-          Test of xxx method, of class org.owasp.esapi.User.
- voidtestIncrementFailedLoginCount() - -
-          Test of incrementFailedLoginCount method, of class org.owasp.esapi.User.
- voidtestIsEnabled() - -
-          Test of isEnabled method, of class org.owasp.esapi.User.
- voidtestIsInRole() - -
-          Test of isInRole method, of class org.owasp.esapi.User.
- voidtestIsLocked() - -
-          Test of xxx method, of class org.owasp.esapi.User.
- voidtestIsSessionAbsoluteTimeout() - -
-          Test of isSessionAbsoluteTimeout method, of class - org.owasp.esapi.IntrusionDetector.
- voidtestIsSessionTimeout() - -
-          Test of isSessionTimeout method, of class - org.owasp.esapi.IntrusionDetector.
- voidtestLock() - -
-          Test of lockAccount method, of class org.owasp.esapi.User.
- voidtestLoginWithPassword() - -
-          Test of loginWithPassword method, of class org.owasp.esapi.User.
- voidtestLogout() - -
-          Test of logout method, of class org.owasp.esapi.User.
- voidtestRemoveRole() - -
-          Test of testRemoveRole method, of class org.owasp.esapi.User.
- voidtestResetCSRFToken() - -
-          Test of testResetCSRFToken method, of class org.owasp.esapi.User.
- voidtestResetPassword() - -
-          Test reset password.
- voidtestResetRememberToken() - -
-          Test of generateRememberMeToken method, of class org.owasp.esapi.User.
- voidtestSetAccountName() - -
-          Test of setAccountName method, of class org.owasp.esapi.User.
- voidtestSetExpirationTime() - -
-          Test of setExpirationTime method, of class org.owasp.esapi.User.
- voidtestSetRoles() - -
-          Test of setRoles method, of class org.owasp.esapi.User.
- voidtestSetScreenName() - -
-          Test of setScreenName method, of class org.owasp.esapi.User.
- voidtestUnlock() - -
-          Test of unlockAccount method, of class org.owasp.esapi.User.
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-UserTest

-
-public UserTest(java.lang.String testName)
-
-
Instantiates a new user test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testAddRole

-
-public void testAddRole()
-                 throws java.lang.Exception
-
-
Test of testAddRole method, of class org.owasp.esapi.User. -

-

- -
Throws: -
java.lang.Exception
-
-
-
- -

-testAddRoles

-
-public void testAddRoles()
-                  throws AuthenticationException
-
-
Test of addRoles method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testChangePassword

-
-public void testChangePassword()
-                        throws java.lang.Exception
-
-
Test of changePassword method, of class org.owasp.esapi.User. -

-

- -
Throws: -
java.lang.Exception - the exception
-
-
-
- -

-testDisable

-
-public void testDisable()
-                 throws AuthenticationException
-
-
Test of disable method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testEnable

-
-public void testEnable()
-                throws AuthenticationException
-
-
Test of enable method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testEquals

-
-public void testEquals()
-                throws AuthenticationException
-
-
Test equals. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testFailedLoginLockout

-
-public void testFailedLoginLockout()
-                            throws AuthenticationException,
-                                   EncryptionException
-
-
Test of failedLoginCount lockout, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception -
EncryptionException
-
-
-
- -

-testGetAccountName

-
-public void testGetAccountName()
-                        throws AuthenticationException
-
-
Test of getAccountName method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testGetLastFailedLoginTime

-
-public void testGetLastFailedLoginTime()
-                                throws java.lang.Exception
-
-
Test get last failed login time. -

-

- -
Throws: -
java.lang.Exception - the exception
-
-
-
- -

-testGetLastLoginTime

-
-public void testGetLastLoginTime()
-                          throws java.lang.Exception
-
-
Test get last login time. -

-

- -
Throws: -
java.lang.Exception - the exception
-
-
-
- -

-testGetLastPasswordChangeTime

-
-public void testGetLastPasswordChangeTime()
-                                   throws java.lang.Exception
-
-
Test of getLastPasswordChangeTime method, of class org.owasp.esapi.User. -

-

- -
Throws: -
java.lang.Exception - the exception
-
-
-
- -

-testGetRoles

-
-public void testGetRoles()
-                  throws java.lang.Exception
-
-
Test of getRoles method, of class org.owasp.esapi.User. -

-

- -
Throws: -
java.lang.Exception
-
-
-
- -

-testGetScreenName

-
-public void testGetScreenName()
-                       throws AuthenticationException
-
-
Test of xxx method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testIncrementFailedLoginCount

-
-public void testIncrementFailedLoginCount()
-                                   throws AuthenticationException
-
-
Test of incrementFailedLoginCount method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testIsEnabled

-
-public void testIsEnabled()
-                   throws AuthenticationException
-
-
Test of isEnabled method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testIsInRole

-
-public void testIsInRole()
-                  throws AuthenticationException
-
-
Test of isInRole method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testIsLocked

-
-public void testIsLocked()
-                  throws AuthenticationException
-
-
Test of xxx method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testIsSessionAbsoluteTimeout

-
-public void testIsSessionAbsoluteTimeout()
-                                  throws AuthenticationException
-
-
Test of isSessionAbsoluteTimeout method, of class - org.owasp.esapi.IntrusionDetector. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testIsSessionTimeout

-
-public void testIsSessionTimeout()
-                          throws AuthenticationException
-
-
Test of isSessionTimeout method, of class - org.owasp.esapi.IntrusionDetector. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testLock

-
-public void testLock()
-              throws AuthenticationException
-
-
Test of lockAccount method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testLoginWithPassword

-
-public void testLoginWithPassword()
-                           throws AuthenticationException
-
-
Test of loginWithPassword method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testLogout

-
-public void testLogout()
-                throws AuthenticationException
-
-
Test of logout method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testRemoveRole

-
-public void testRemoveRole()
-                    throws AuthenticationException
-
-
Test of testRemoveRole method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testResetCSRFToken

-
-public void testResetCSRFToken()
-                        throws AuthenticationException
-
-
Test of testResetCSRFToken method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testResetPassword

-
-public void testResetPassword()
-                       throws AuthenticationException,
-                              EncryptionException
-
-
Test reset password. -

-

- -
Throws: -
AuthenticationException - the authentication exception -
EncryptionException
-
-
-
- -

-testResetRememberToken

-
-public void testResetRememberToken()
-                            throws AuthenticationException
-
-
Test of generateRememberMeToken method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testSetAccountName

-
-public void testSetAccountName()
-                        throws AuthenticationException
-
-
Test of setAccountName method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException
-
-
-
- -

-testSetExpirationTime

-
-public void testSetExpirationTime()
-                           throws java.lang.Exception
-
-
Test of setExpirationTime method, of class org.owasp.esapi.User. -

-

- -
Throws: -
java.lang.Exception
-
-
-
- -

-testSetRoles

-
-public void testSetRoles()
-                  throws AuthenticationException
-
-
Test of setRoles method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testSetScreenName

-
-public void testSetScreenName()
-                       throws AuthenticationException
-
-
Test of setScreenName method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testUnlock

-
-public void testUnlock()
-                throws AuthenticationException
-
-
Test of unlockAccount method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/ValidationAvailabilityException.html b/javadoc/org/owasp/esapi/ValidationAvailabilityException.html deleted file mode 100644 index bfa38f9c1..000000000 --- a/javadoc/org/owasp/esapi/ValidationAvailabilityException.html +++ /dev/null @@ -1,277 +0,0 @@ - - - - - - -ValidationAvailabilityException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class ValidationAvailabilityException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.EnterpriseSecurityException
-              extended byorg.owasp.esapi.ValidationException
-                  extended byorg.owasp.esapi.ValidationAvailabilityException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
-
public class ValidationAvailabilityException
extends ValidationException
- -

-FIXME: DOC. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
ValidationAvailabilityException(java.lang.String userMessage, - java.lang.String logMessage) - -
-          Create a new ValidationException
ValidationAvailabilityException(java.lang.String userMessage, - java.lang.String logMessage, - java.lang.Throwable cause) - -
-          Create a new ValidationException
-  - - - - - - - - - - -
Methods inherited from class org.owasp.esapi.EnterpriseSecurityException
getLogMessage, getUserMessage
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-ValidationAvailabilityException

-
-public ValidationAvailabilityException(java.lang.String userMessage,
-                                       java.lang.String logMessage)
-
-
Create a new ValidationException -

-

Parameters:
userMessage -
logMessage -
-
- -

-ValidationAvailabilityException

-
-public ValidationAvailabilityException(java.lang.String userMessage,
-                                       java.lang.String logMessage,
-                                       java.lang.Throwable cause)
-
-
Create a new ValidationException -

-

Parameters:
userMessage -
logMessage -
cause -
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/ValidationErrorList.html b/javadoc/org/owasp/esapi/ValidationErrorList.html deleted file mode 100644 index 13e30a296..000000000 --- a/javadoc/org/owasp/esapi/ValidationErrorList.html +++ /dev/null @@ -1,408 +0,0 @@ - - - - - - -ValidationErrorList - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class ValidationErrorList

-
-java.lang.Object
-  extended byorg.owasp.esapi.ValidationErrorList
-
-
-
-
public class ValidationErrorList
extends java.lang.Object
- -

-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: - -

- ValidationErrorList() errorList = new ValidationErrorList();.
- String name  = getValidInput("Name", form.getName(), "SomeESAPIRegExName1", 255, false, errorList);
- String address = getValidInput("Address", form.getAddress(), "SomeESAPIRegExName2", 255, false, errorList);
- Integer weight = getValidInteger("Weight", form.getWeight(), 1, 1000000000, false, errorList);
- Integer sortOrder = getValidInteger("Sort Order", form.getSortOrder(), -100000, +100000, false, errorList);
- request.setAttribute( "ERROR_LIST", errorList );
- 
- - The at your view layer you would be able to retrieve all - of your error messages via a helper function like: - -
- public static ValidationErrorList getErrors() {          
-     HttpServletRequest request = ESAPI.httpUtilities().getCurrentRequest();
-     ValidationErrorList errors = new ValidationErrorList();
-     if (request.getAttribute(Constants.ERROR_LIST) != null) {
-        errors = (ValidationErrorList)request.getAttribute("ERROR_LIST");
-     }
- 	   return errors;
- }
- 
- - You can list all errors like: - -
- <%
-      for (Object vo : errorList.errors()) {
-         ValidationException ve = (ValidationException)vo;
- %>
- <%= ESAPI.encoder().encodeForHTML(ve.getMessage()) %>
- <% - } - %> -
- - And even check if a specific UI component is in error via calls like: - -
- ValidationException e = errorList.getError("Name");
- 
-

- -

-

-
Since:
-
August 15, 2008
-
Author:
-
Jim Manico (jim.manico .at. aspectsecurity.com) - Aspect Security
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
ValidationErrorList() - -
-           
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- voidaddError(java.lang.String context, - ValidationException ve) - -
-          Adds a new error to list with a unique named context.
- java.util.Listerrors() - -
-          Returns list of ValidationException, or empty list of no errors exist.
- ValidationExceptiongetError(java.lang.String context) - -
-          Retrieves ValidationException for given context if one exists.
- booleanisEmpty() - -
-          Returns true if no error are present.
- intsize() - -
-          Returns the numbers of errors present.
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-ValidationErrorList

-
-public ValidationErrorList()
-
-
- - - - - - - - -
-Method Detail
- -

-addError

-
-public void addError(java.lang.String context,
-                     ValidationException ve)
-
-
Adds a new error to list with a unique named context. - No action taken if either element is null. - Existing contexts will be overwritten. -

-

-
Parameters:
context - unique named context for this ValidationErrorList
ve -
-
-
-
- -

-errors

-
-public java.util.List errors()
-
-
Returns list of ValidationException, or empty list of no errors exist. -

-

- -
Returns:
List
-
-
-
- -

-getError

-
-public ValidationException getError(java.lang.String context)
-
-
Retrieves ValidationException for given context if one exists. -

-

-
Parameters:
context - unique name for each error -
Returns:
ValidationException or null for given context
-
-
-
- -

-isEmpty

-
-public boolean isEmpty()
-
-
Returns true if no error are present. -

-

- -
Returns:
boolean
-
-
-
- -

-size

-
-public int size()
-
-
Returns the numbers of errors present. -

-

- -
Returns:
boolean
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/ValidationException.html b/javadoc/org/owasp/esapi/ValidationException.html deleted file mode 100644 index c4b0ded5a..000000000 --- a/javadoc/org/owasp/esapi/ValidationException.html +++ /dev/null @@ -1,281 +0,0 @@ - - - - - - -ValidationException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class ValidationException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.EnterpriseSecurityException
-              extended byorg.owasp.esapi.ValidationException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
Direct Known Subclasses:
ValidationAvailabilityException, ValidationUploadException
-
-
-
-
public class ValidationException
extends EnterpriseSecurityException
- -

-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. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
ValidationException(java.lang.String userMessage, - java.lang.String logMessage) - -
-          Creates a new instance of ValidationException.
ValidationException(java.lang.String userMessage, - java.lang.String logMessage, - java.lang.Throwable cause) - -
-          Instantiates a new ValidationException.
-  - - - - - - - - - - -
Methods inherited from class org.owasp.esapi.EnterpriseSecurityException
getLogMessage, getUserMessage
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-ValidationException

-
-public ValidationException(java.lang.String userMessage,
-                           java.lang.String logMessage)
-
-
Creates a new instance of ValidationException. -

-

-
- -

-ValidationException

-
-public ValidationException(java.lang.String userMessage,
-                           java.lang.String logMessage,
-                           java.lang.Throwable cause)
-
-
Instantiates a new ValidationException. -

-

Parameters:
cause - the cause
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/ValidationUploadException.html b/javadoc/org/owasp/esapi/ValidationUploadException.html deleted file mode 100644 index 4d39d6426..000000000 --- a/javadoc/org/owasp/esapi/ValidationUploadException.html +++ /dev/null @@ -1,277 +0,0 @@ - - - - - - -ValidationUploadException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class ValidationUploadException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.EnterpriseSecurityException
-              extended byorg.owasp.esapi.ValidationException
-                  extended byorg.owasp.esapi.ValidationUploadException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
-
public class ValidationUploadException
extends ValidationException
- -

-FIXME: DOC. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
ValidationUploadException(java.lang.String userMessage, - java.lang.String logMessage) - -
-          Create a new ValidationException
ValidationUploadException(java.lang.String userMessage, - java.lang.String logMessage, - java.lang.Throwable cause) - -
-          Create a new ValidationException
-  - - - - - - - - - - -
Methods inherited from class org.owasp.esapi.EnterpriseSecurityException
getLogMessage, getUserMessage
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-ValidationUploadException

-
-public ValidationUploadException(java.lang.String userMessage,
-                                 java.lang.String logMessage)
-
-
Create a new ValidationException -

-

Parameters:
userMessage -
logMessage -
-
- -

-ValidationUploadException

-
-public ValidationUploadException(java.lang.String userMessage,
-                                 java.lang.String logMessage,
-                                 java.lang.Throwable cause)
-
-
Create a new ValidationException -

-

Parameters:
userMessage -
logMessage -
cause -
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/Validator.html b/javadoc/org/owasp/esapi/Validator.html deleted file mode 100644 index 143e7ac71..000000000 --- a/javadoc/org/owasp/esapi/Validator.html +++ /dev/null @@ -1,1926 +0,0 @@ - - - - - - -Validator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Interface Validator

-
-
All Known Implementing Classes:
DefaultValidator
-
-
-
-
public interface Validator
- -

-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
- voidassertIsValidHTTPRequest() - -
-          Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed - characters.
- voidassertIsValidHTTPRequestParameterSet(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.
- voidassertIsValidHTTPRequestParameterSet(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.
- voidassertValidFileUpload(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.
- voidassertValidFileUpload(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.StringgetValidCreditCard(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated credit card number as a String.
- java.lang.StringgetValidCreditCard(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.DategetValidDate(java.lang.String context, - java.lang.String input, - java.text.DateFormat format, - boolean allowNull) - -
-          Returns a valid date as a Date.
- java.util.DategetValidDate(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.StringgetValidDirectoryPath(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated directory path as a String.
- java.lang.StringgetValidDirectoryPath(java.lang.String context, - java.lang.String input, - boolean allowNull, - ValidationErrorList errorList) - -
-          Returns a canonicalized and validated directory path as a String.
- java.lang.DoublegetValidDouble(java.lang.String context, - java.lang.String input, - double minValue, - double maxValue, - boolean allowNull) - -
-          Returns a validated real number as a double.
- java.lang.DoublegetValidDouble(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.StringgetValidFileName(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated file name as a String.
- java.lang.StringgetValidFileName(java.lang.String context, - java.lang.String input, - boolean allowNull, - ValidationErrorList errorList) - -
-          Returns a canonicalized and validated file name as a String.
- java.lang.StringgetValidInput(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.StringgetValidInput(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.IntegergetValidInteger(java.lang.String context, - java.lang.String input, - int minValue, - int maxValue, - boolean allowNull) - -
-          Returns a validated integer.
- java.lang.IntegergetValidInteger(java.lang.String context, - java.lang.String input, - int minValue, - int maxValue, - boolean allowNull, - ValidationErrorList errorList) - -
-          Returns a validated integer.
- java.lang.StringgetValidListItem(java.lang.String context, - java.lang.String input, - java.util.List list) - -
-          Returns the list item that exactly matches the canonicalized input.
- java.lang.StringgetValidListItem(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.DoublegetValidNumber(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.DoublegetValidNumber(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.StringgetValidPrintable(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-          Returns canonicalized and validated printable characters as a String.
- java.lang.StringgetValidPrintable(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.StringgetValidRedirectLocation(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated redirect location as a String.
- java.lang.StringgetValidRedirectLocation(java.lang.String context, - java.lang.String input, - boolean allowNull, - ValidationErrorList errorList) - -
-          Returns a canonicalized and validated redirect location as a String.
- java.lang.StringgetValidSafeHTML(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-          Returns canonicalized and validated "safe" HTML.
- java.lang.StringgetValidSafeHTML(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull, - ValidationErrorList errorList) - -
-          Returns canonicalized and validated "safe" HTML.
- booleanisValidCreditCard(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns true if input is a valid credit card.
- booleanisValidDate(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.
- booleanisValidDirectoryPath(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns true if input is a valid directory path.
- booleanisValidDouble(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.
- booleanisValidFileContent(java.lang.String context, - byte[] input, - int maxBytes, - boolean allowNull) - -
-          Returns true if input is valid file content.
- booleanisValidFileName(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns true if input is a valid file name.
- booleanisValidFileUpload(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.
- booleanisValidHTTPRequest() - -
-          Validate the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed - characters.
- booleanisValidHTTPRequestParameterSet(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.
- booleanisValidInput(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.
- booleanisValidInteger(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.
- booleanisValidListItem(java.lang.String context, - java.lang.String input, - java.util.List list) - -
-          Returns true if input is a valid list item.
- booleanisValidNumber(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.
- booleanisValidPrintable(java.lang.String context, - byte[] input, - int maxLength, - boolean allowNull) - -
-          Returns true if input contains only valid printable ASCII characters.
- booleanisValidPrintable(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-          Returns true if input contains only valid printable ASCII characters (32-126).
- booleanisValidRedirectLocation(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns true if input is a valid redirect location, as defined by "ESAPI.properties".
- booleanisValidSafeHTML(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-          Returns true if input is "safe" HTML.
- java.lang.StringsafeReadLine(java.io.InputStream inputStream, - int maxLength) - -
-          Reads from an input stream until end-of-line or a maximum number of - characters.
-  -

- - - - - - - - - - - - - - -
-Method Detail
- -

-isValidInput

-
-public boolean isValidInput(java.lang.String context,
-                            java.lang.String input,
-                            java.lang.String type,
-                            int maxLength,
-                            boolean allowNull)
-                     throws IntrusionException
-
-
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' -
Throws: -
IntrusionException
-
-
-
- -

-getValidInput

-
-public java.lang.String getValidInput(java.lang.String context,
-                                      java.lang.String input,
-                                      java.lang.String type,
-                                      int maxLength,
-                                      boolean allowNull)
-                               throws ValidationException,
-                                      IntrusionException
-
-
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:
The canonicalized user input. -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-getValidInput

-
-public java.lang.String getValidInput(java.lang.String context,
-                                      java.lang.String input,
-                                      java.lang.String type,
-                                      int maxLength,
-                                      boolean allowNull,
-                                      ValidationErrorList errorList)
-                               throws IntrusionException
-
-
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:
The canonicalized user input. -
Throws: -
IntrusionException
-
-
-
- -

-isValidDate

-
-public boolean isValidDate(java.lang.String context,
-                           java.lang.String input,
-                           java.text.DateFormat format,
-                           boolean allowNull)
-                    throws IntrusionException
-
-
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' -
Throws: -
IntrusionException
-
-
-
- -

-getValidDate

-
-public java.util.Date getValidDate(java.lang.String context,
-                                   java.lang.String input,
-                                   java.text.DateFormat format,
-                                   boolean allowNull)
-                            throws ValidationException,
-                                   IntrusionException
-
-
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 -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-getValidDate

-
-public java.util.Date getValidDate(java.lang.String context,
-                                   java.lang.String input,
-                                   java.text.DateFormat format,
-                                   boolean allowNull,
-                                   ValidationErrorList errorList)
-                            throws IntrusionException
-
-
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:
A valid date as a Date -
Throws: -
IntrusionException
-
-
-
- -

-isValidSafeHTML

-
-public boolean isValidSafeHTML(java.lang.String context,
-                               java.lang.String input,
-                               int maxLength,
-                               boolean allowNull)
-                        throws 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. -

-

-
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:
true, if input is valid safe HTML -
Throws: -
IntrusionException
-
-
-
- -

-getValidSafeHTML

-
-public java.lang.String getValidSafeHTML(java.lang.String context,
-                                         java.lang.String input,
-                                         int maxLength,
-                                         boolean allowNull)
-                                  throws ValidationException,
-                                         IntrusionException
-
-
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:
Valid safe HTML -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-getValidSafeHTML

-
-public java.lang.String getValidSafeHTML(java.lang.String context,
-                                         java.lang.String input,
-                                         int maxLength,
-                                         boolean allowNull,
-                                         ValidationErrorList errorList)
-                                  throws IntrusionException
-
-
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:
Valid safe HTML -
Throws: -
IntrusionException
-
-
-
- -

-isValidCreditCard

-
-public boolean isValidCreditCard(java.lang.String context,
-                                 java.lang.String input,
-                                 boolean allowNull)
-                          throws IntrusionException
-
-
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:
true, if input is a valid credit card number -
Throws: -
IntrusionException
-
-
-
- -

-getValidCreditCard

-
-public java.lang.String getValidCreditCard(java.lang.String context,
-                                           java.lang.String input,
-                                           boolean allowNull)
-                                    throws ValidationException,
-                                           IntrusionException
-
-
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 valid credit card number -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-getValidCreditCard

-
-public java.lang.String getValidCreditCard(java.lang.String context,
-                                           java.lang.String input,
-                                           boolean allowNull,
-                                           ValidationErrorList errorList)
-                                    throws IntrusionException
-
-
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:
A valid credit card number -
Throws: -
IntrusionException
-
-
-
- -

-isValidDirectoryPath

-
-public boolean isValidDirectoryPath(java.lang.String context,
-                                    java.lang.String input,
-                                    boolean allowNull)
-                             throws IntrusionException
-
-
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:
true, if input is a valid directory path -
Throws: -
IntrusionException
-
-
-
- -

-getValidDirectoryPath

-
-public java.lang.String getValidDirectoryPath(java.lang.String context,
-                                              java.lang.String input,
-                                              boolean allowNull)
-                                       throws ValidationException,
-                                              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. -

-

-
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 valid directory path -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-getValidDirectoryPath

-
-public java.lang.String getValidDirectoryPath(java.lang.String context,
-                                              java.lang.String input,
-                                              boolean allowNull,
-                                              ValidationErrorList errorList)
-                                       throws 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. 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:
A valid directory path -
Throws: -
IntrusionException
-
-
-
- -

-isValidFileName

-
-public boolean isValidFileName(java.lang.String context,
-                               java.lang.String input,
-                               boolean allowNull)
-                        throws IntrusionException
-
-
Returns true if input is a valid file name. -

-

-
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:
true, if input is a valid file name -
Throws: -
IntrusionException
-
-
-
- -

-getValidFileName

-
-public java.lang.String getValidFileName(java.lang.String context,
-                                         java.lang.String input,
-                                         boolean allowNull)
-                                  throws ValidationException,
-                                         IntrusionException
-
-
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 valid file name -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-getValidFileName

-
-public java.lang.String getValidFileName(java.lang.String context,
-                                         java.lang.String input,
-                                         boolean allowNull,
-                                         ValidationErrorList errorList)
-                                  throws IntrusionException
-
-
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 -
Returns:
A valid file name -
Throws: -
IntrusionException
-
-
-
- -

-isValidNumber

-
-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:
true, if input is a valid number -
Throws: -
IntrusionException
-
-
-
- -

-getValidNumber

-
-public java.lang.Double getValidNumber(java.lang.String context,
-                                       java.lang.String input,
-                                       long minValue,
-                                       long maxValue,
-                                       boolean allowNull)
-                                throws ValidationException,
-                                       IntrusionException
-
-
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.
minValue - Lowest legal value for input.
maxValue - Highest legal value for input. -
Returns:
A validated number as a double. -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-getValidNumber

-
-public java.lang.Double getValidNumber(java.lang.String context,
-                                       java.lang.String input,
-                                       long minValue,
-                                       long maxValue,
-                                       boolean allowNull,
-                                       ValidationErrorList errorList)
-                                throws IntrusionException
-
-
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 -
Returns:
A validated number as a double. -
Throws: -
IntrusionException
-
-
-
- -

-isValidInteger

-
-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:
true, if input is a valid integer -
Throws: -
IntrusionException
-
-
-
- -

-getValidInteger

-
-public java.lang.Integer getValidInteger(java.lang.String context,
-                                         java.lang.String input,
-                                         int minValue,
-                                         int maxValue,
-                                         boolean allowNull)
-                                  throws ValidationException,
-                                         IntrusionException
-
-
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.
minValue - Lowest legal value for input.
maxValue - Highest legal value for input. -
Returns:
A validated number as an integer. -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-getValidInteger

-
-public java.lang.Integer getValidInteger(java.lang.String context,
-                                         java.lang.String input,
-                                         int minValue,
-                                         int maxValue,
-                                         boolean allowNull,
-                                         ValidationErrorList errorList)
-                                  throws IntrusionException
-
-
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:
A validated number as an integer. -
Throws: -
IntrusionException
-
-
-
- -

-isValidDouble

-
-public boolean isValidDouble(java.lang.String context,
-                             java.lang.String input,
-                             double minValue,
-                             double maxValue,
-                             boolean allowNull)
-                      throws IntrusionException
-
-
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:
true, if input is a valid double. -
Throws: -
IntrusionException
-
-
-
- -

-getValidDouble

-
-public java.lang.Double getValidDouble(java.lang.String context,
-                                       java.lang.String input,
-                                       double minValue,
-                                       double maxValue,
-                                       boolean allowNull)
-                                throws ValidationException,
-                                       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. -

-

-
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.
minValue - Lowest legal value for input.
maxValue - Highest legal value for input. -
Returns:
A validated real number as a double. -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-getValidDouble

-
-public java.lang.Double getValidDouble(java.lang.String context,
-                                       java.lang.String input,
-                                       double minValue,
-                                       double maxValue,
-                                       boolean allowNull,
-                                       ValidationErrorList errorList)
-                                throws 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. 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:
A validated real number as a double. -
Throws: -
IntrusionException
-
-
-
- -

-isValidFileContent

-
-public boolean isValidFileContent(java.lang.String context,
-                                  byte[] input,
-                                  int maxBytes,
-                                  boolean allowNull)
-                           throws IntrusionException
-
-
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:
true, if input contains valid file content. -
Throws: -
IntrusionException
-
-
-
- -

-getValidFileContent

-
-public byte[] getValidFileContent(java.lang.String context,
-                                  byte[] input,
-                                  int maxBytes,
-                                  boolean allowNull)
-                           throws ValidationException,
-                                  IntrusionException
-
-
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:
A byte array containing valid file content. -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-getValidFileContent

-
-public byte[] getValidFileContent(java.lang.String context,
-                                  byte[] input,
-                                  int maxBytes,
-                                  boolean allowNull,
-                                  ValidationErrorList errorList)
-                           throws IntrusionException
-
-
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:
A byte array containing valid file content. -
Throws: -
IntrusionException
-
-
-
- -

-isValidFileUpload

-
-public boolean isValidFileUpload(java.lang.String context,
-                                 java.lang.String filepath,
-                                 java.lang.String filename,
-                                 byte[] content,
-                                 int maxBytes,
-                                 boolean allowNull)
-                          throws IntrusionException
-
-
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. -
Throws: -
IntrusionException
-
-
-
- -

-assertValidFileUpload

-
-public void assertValidFileUpload(java.lang.String context,
-                                  java.lang.String filepath,
-                                  java.lang.String filename,
-                                  byte[] content,
-                                  int maxBytes,
-                                  boolean allowNull)
-                           throws ValidationException,
-                                  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. -

-

-
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. -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-assertValidFileUpload

-
-public void assertValidFileUpload(java.lang.String context,
-                                  java.lang.String filepath,
-                                  java.lang.String filename,
-                                  byte[] content,
-                                  int maxBytes,
-                                  boolean allowNull,
-                                  ValidationErrorList errorList)
-                           throws 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. 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 -
Throws: -
IntrusionException
-
-
-
- -

-isValidHTTPRequest

-
-public boolean isValidHTTPRequest()
-                           throws 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. -

-

- -
Returns:
true, if is a valid HTTP request -
Throws: -
IntrusionException
-
-
-
- -

-assertIsValidHTTPRequest

-
-public void assertIsValidHTTPRequest()
-                              throws ValidationException,
-                                     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. -

-

- -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-isValidListItem

-
-public boolean isValidListItem(java.lang.String context,
-                               java.lang.String input,
-                               java.util.List list)
-                        throws IntrusionException
-
-
Returns true if input is a valid list item. -

-

-
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:
true, if 'input' was found in 'list'. -
Throws: -
IntrusionException
-
-
-
- -

-getValidListItem

-
-public java.lang.String getValidListItem(java.lang.String context,
-                                         java.lang.String input,
-                                         java.util.List list)
-                                  throws ValidationException,
-                                         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. -

-

-
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. -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-getValidListItem

-
-public java.lang.String getValidListItem(java.lang.String context,
-                                         java.lang.String input,
-                                         java.util.List list,
-                                         ValidationErrorList errorList)
-                                  throws 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. 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. -
Throws: -
IntrusionException
-
-
-
- -

-isValidHTTPRequestParameterSet

-
-public boolean isValidHTTPRequestParameterSet(java.lang.String context,
-                                              java.util.Set required,
-                                              java.util.Set optional)
-                                       throws IntrusionException
-
-
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. -
Throws: -
IntrusionException
-
-
-
- -

-assertIsValidHTTPRequestParameterSet

-
-public void assertIsValidHTTPRequestParameterSet(java.lang.String context,
-                                                 java.util.Set required,
-                                                 java.util.Set optional)
-                                          throws ValidationException,
-                                                 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. -

-

-
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 -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-assertIsValidHTTPRequestParameterSet

-
-public void assertIsValidHTTPRequestParameterSet(java.lang.String context,
-                                                 java.util.Set required,
-                                                 java.util.Set optional,
-                                                 ValidationErrorList errorList)
-                                          throws 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. 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 -
Throws: -
IntrusionException
-
-
-
- -

-isValidPrintable

-
-public boolean isValidPrintable(java.lang.String context,
-                                byte[] input,
-                                int maxLength,
-                                boolean allowNull)
-                         throws IntrusionException
-
-
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 -
Throws: -
IntrusionException
-
-
-
- -

-getValidPrintable

-
-public byte[] getValidPrintable(java.lang.String context,
-                                byte[] input,
-                                int maxLength,
-                                boolean allowNull)
-                         throws ValidationException
-
-
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' -
Throws: -
ValidationException
-
-
-
- -

-getValidPrintable

-
-public byte[] getValidPrintable(java.lang.String context,
-                                byte[] input,
-                                int maxLength,
-                                boolean allowNull,
-                                ValidationErrorList errorList)
-                         throws 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. 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' -
Throws: -
IntrusionException
-
-
-
- -

-isValidPrintable

-
-public boolean isValidPrintable(java.lang.String context,
-                                java.lang.String input,
-                                int maxLength,
-                                boolean allowNull)
-                         throws IntrusionException
-
-
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 -
Throws: -
IntrusionException
-
-
-
- -

-getValidPrintable

-
-public java.lang.String getValidPrintable(java.lang.String context,
-                                          java.lang.String input,
-                                          int maxLength,
-                                          boolean allowNull)
-                                   throws ValidationException
-
-
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' -
Throws: -
ValidationException
-
-
-
- -

-getValidPrintable

-
-public java.lang.String getValidPrintable(java.lang.String context,
-                                          java.lang.String input,
-                                          int maxLength,
-                                          boolean allowNull,
-                                          ValidationErrorList errorList)
-                                   throws 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. 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' -
Throws: -
IntrusionException
-
-
-
- -

-isValidRedirectLocation

-
-public boolean isValidRedirectLocation(java.lang.String context,
-                                       java.lang.String input,
-                                       boolean allowNull)
-                                throws IntrusionException
-
-
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. -
Throws: -
IntrusionException
-
-
-
- -

-getValidRedirectLocation

-
-public java.lang.String getValidRedirectLocation(java.lang.String context,
-                                                 java.lang.String input,
-                                                 boolean allowNull)
-                                          throws ValidationException,
-                                                 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. -

-

-
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" -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-getValidRedirectLocation

-
-public java.lang.String getValidRedirectLocation(java.lang.String context,
-                                                 java.lang.String input,
-                                                 boolean allowNull,
-                                                 ValidationErrorList errorList)
-                                          throws 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. 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" -
Throws: -
IntrusionException
-
-
-
- -

-safeReadLine

-
-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 -
Throws: -
ValidationException
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/ValidatorTest.html b/javadoc/org/owasp/esapi/ValidatorTest.html deleted file mode 100644 index 71caaa911..000000000 --- a/javadoc/org/owasp/esapi/ValidatorTest.html +++ /dev/null @@ -1,605 +0,0 @@ - - - - - - -ValidatorTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi -
-Class ValidatorTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.ValidatorTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class ValidatorTest
extends junit.framework.TestCase
- -

-The Class ValidatorTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
ValidatorTest(java.lang.String testName) - -
-          Instantiates a new validator test.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestGetValidDate() - -
-          Test of getValidDate method, of class org.owasp.esapi.Validator.
- voidtestGetValidSafeHTML() - -
-          Test of getValidSafeHTML method, of class org.owasp.esapi.Validator.
- voidtestIsValidCreditCard() - -
-          Test of isValidCreditCard method, of class org.owasp.esapi.Validator.
- voidtestIsValidDirectoryPath() - -
-          Test of isValidDirectoryPath method, of class org.owasp.esapi.Validator.
- voidtestIsValidFileContent() - -
-          Test of isValidFileContent method, of class org.owasp.esapi.Validator.
- voidtestIsValidFileName() - -
-          Test of isValidFileName method, of class org.owasp.esapi.Validator.
- voidtestIsValidFileUpload() - -
-          Test of isValidFileUpload method, of class org.owasp.esapi.Validator.
- voidtestisValidInput() - -
-          Test of isValidEmailAddress method, of class org.owasp.esapi.Validator.
- voidtestIsValidInteger() - -
-           
- voidtestIsValidListItem() - -
-          Test of isValidListItem method, of class org.owasp.esapi.Validator.
- voidtestIsValidNumber() - -
-          Test of isValidNumber method, of class org.owasp.esapi.Validator.
- voidtestIsValidParameterSet() - -
-          Test of isValidParameterSet method, of class org.owasp.esapi.Validator.
- voidtestIsValidPrintable() - -
-           
- voidtestIsValidSafeHTML() - -
-          Test of isValidSafeHTML method, of class org.owasp.esapi.Validator.
- voidtestSafeReadLine() - -
-          Test safe read line.
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-ValidatorTest

-
-public ValidatorTest(java.lang.String testName)
-
-
Instantiates a new validator test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testIsValidCreditCard

-
-public void testIsValidCreditCard()
-
-
Test of isValidCreditCard method, of class org.owasp.esapi.Validator. -

-

-
-
-
-
- -

-testisValidInput

-
-public void testisValidInput()
-
-
Test of isValidEmailAddress method, of class org.owasp.esapi.Validator. -

-

-
-
-
-
- -

-testIsValidSafeHTML

-
-public void testIsValidSafeHTML()
-
-
Test of isValidSafeHTML method, of class org.owasp.esapi.Validator. -

-

-
-
-
-
- -

-testGetValidSafeHTML

-
-public void testGetValidSafeHTML()
-                          throws java.lang.Exception
-
-
Test of getValidSafeHTML method, of class org.owasp.esapi.Validator. -

-

- -
Throws: -
java.lang.Exception
-
-
-
- -

-testIsValidListItem

-
-public void testIsValidListItem()
-
-
Test of isValidListItem method, of class org.owasp.esapi.Validator. -

-

-
-
-
-
- -

-testIsValidNumber

-
-public void testIsValidNumber()
-
-
Test of isValidNumber method, of class org.owasp.esapi.Validator. -

-

-
-
-
-
- -

-testIsValidInteger

-
-public void testIsValidInteger()
-
-
-
-
-
-
- -

-testGetValidDate

-
-public void testGetValidDate()
-                      throws java.lang.Exception
-
-
Test of getValidDate method, of class org.owasp.esapi.Validator. -

-

- -
Throws: -
java.lang.Exception
-
-
-
- -

-testIsValidFileName

-
-public void testIsValidFileName()
-
-
Test of isValidFileName method, of class org.owasp.esapi.Validator. -

-

-
-
-
-
- -

-testIsValidDirectoryPath

-
-public void testIsValidDirectoryPath()
-
-
Test of isValidDirectoryPath method, of class org.owasp.esapi.Validator. -

-

-
-
-
-
- -

-testIsValidPrintable

-
-public void testIsValidPrintable()
-
-
-
-
-
-
- -

-testIsValidFileContent

-
-public void testIsValidFileContent()
-
-
Test of isValidFileContent method, of class org.owasp.esapi.Validator. -

-

-
-
-
-
- -

-testIsValidFileUpload

-
-public void testIsValidFileUpload()
-
-
Test of isValidFileUpload method, of class org.owasp.esapi.Validator. -

-

-
-
-
-
- -

-testIsValidParameterSet

-
-public void testIsValidParameterSet()
-
-
Test of isValidParameterSet method, of class org.owasp.esapi.Validator. -

-

-
-
-
-
- -

-testSafeReadLine

-
-public void testSafeReadLine()
-
-
Test safe read line. -

-

-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/AccessControlException.html b/javadoc/org/owasp/esapi/class-use/AccessControlException.html deleted file mode 100644 index b23d606f6..000000000 --- a/javadoc/org/owasp/esapi/class-use/AccessControlException.html +++ /dev/null @@ -1,333 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.AccessControlException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.AccessControlException

-
- - - - - - - - - - - - - -
-Packages that use AccessControlException
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceReference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of AccessControlException in org.owasp.esapi
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi that throw AccessControlException
- voidAccessController.assertAuthorizedForURL(java.lang.String url) - -
-          Checks if an account is authorized to access the referenced URL.
- voidAccessController.assertAuthorizedForFunction(java.lang.String functionName) - -
-          Checks if an account is authorized to access the referenced function.
- voidAccessController.assertAuthorizedForData(java.lang.String key) - -
-          Checks if an account is authorized to access the referenced data.
- voidAccessController.assertAuthorizedForFile(java.lang.String filepath) - -
-          Checks if an account is authorized to access the referenced file.
- voidAccessController.assertAuthorizedForService(java.lang.String serviceName) - -
-          Checks if an account is authorized to access the referenced service.
- voidHTTPUtilities.assertSecureRequest() - -
-          Ensures that the current request uses SSL and POST to protect any sensitive parameters - in the querystring from being sniffed or logged.
- voidHTTPUtilities.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.ObjectAccessReferenceMap.getDirectReference(java.lang.String indirectReference) - -
-          Get the original direct object reference from an indirect reference.
- java.lang.StringAccessReferenceMap.removeDirectReference(java.lang.Object direct) - -
-          Removes a direct reference and its associated indirect reference from the AccessReferenceMap.
- java.lang.StringRandomAccessReferenceMap.removeDirectReference(java.lang.Object direct) - -
-          Remove a direct reference and the corresponding indirect reference.
- java.lang.ObjectRandomAccessReferenceMap.getDirectReference(java.lang.String indirectReference) - -
-           
-  -

- - - - - -
-Uses of AccessControlException in org.owasp.esapi.reference
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi.reference that throw AccessControlException
- voidFileBasedAccessController.assertAuthorizedForURL(java.lang.String url) - -
-           
- voidFileBasedAccessController.assertAuthorizedForFunction(java.lang.String functionName) - -
-           
- voidFileBasedAccessController.assertAuthorizedForData(java.lang.String key) - -
-           
- voidFileBasedAccessController.assertAuthorizedForFile(java.lang.String filepath) - -
-           
- voidFileBasedAccessController.assertAuthorizedForService(java.lang.String serviceName) - -
-           
- voidDefaultHTTPUtilities.assertSecureRequest() - -
-          Checks the method of the current request.
- voidDefaultHTTPUtilities.safeSendForward(java.lang.String context, - java.lang.String location) - -
-           
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/AccessController.html b/javadoc/org/owasp/esapi/class-use/AccessController.html deleted file mode 100644 index 06f62f2d0..000000000 --- a/javadoc/org/owasp/esapi/class-use/AccessController.html +++ /dev/null @@ -1,218 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.AccessController - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.AccessController

-
- - - - - - - - - - - - - -
-Packages that use AccessController
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of AccessController in org.owasp.esapi
-  -

- - - - - - - - - -
Methods in org.owasp.esapi that return AccessController
-static AccessControllerESAPI.accessController() - -
-           
-  -

- - - - - - - - - -
Methods in org.owasp.esapi with parameters of type AccessController
-static voidESAPI.setAccessController(AccessController accessController) - -
-           
-  -

- - - - - -
-Uses of AccessController in org.owasp.esapi.reference
-  -

- - - - - - - - - -
Classes in org.owasp.esapi.reference that implement AccessController
- classFileBasedAccessController - -
-          Reference implementation of the AccessController interface.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/AccessControllerTest.html b/javadoc/org/owasp/esapi/class-use/AccessControllerTest.html deleted file mode 100644 index a88474426..000000000 --- a/javadoc/org/owasp/esapi/class-use/AccessControllerTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.AccessControllerTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.AccessControllerTest

-
-No usage of org.owasp.esapi.AccessControllerTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/AccessReferenceMap.html b/javadoc/org/owasp/esapi/class-use/AccessReferenceMap.html deleted file mode 100644 index 3e8f7e134..000000000 --- a/javadoc/org/owasp/esapi/class-use/AccessReferenceMap.html +++ /dev/null @@ -1,180 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.AccessReferenceMap - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.AccessReferenceMap

-
- - - - - - - - - -
-Packages that use AccessReferenceMap
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of AccessReferenceMap in org.owasp.esapi.reference
-  -

- - - - - - - - - - - - - -
Classes in org.owasp.esapi.reference that implement AccessReferenceMap
- classIntegerAccessReferenceMap - -
-          Reference implementation of the AccessReferenceMap interface.
- classRandomAccessReferenceMap - -
-          Reference implementation of the AccessReferenceMap interface.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/AccessReferenceMapTest.html b/javadoc/org/owasp/esapi/class-use/AccessReferenceMapTest.html deleted file mode 100644 index c824b8819..000000000 --- a/javadoc/org/owasp/esapi/class-use/AccessReferenceMapTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.AccessReferenceMapTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.AccessReferenceMapTest

-
-No usage of org.owasp.esapi.AccessReferenceMapTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/AllTests.html b/javadoc/org/owasp/esapi/class-use/AllTests.html deleted file mode 100644 index e232e1f75..000000000 --- a/javadoc/org/owasp/esapi/class-use/AllTests.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.AllTests - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.AllTests

-
-No usage of org.owasp.esapi.AllTests -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/AuthenticationAccountsException.html b/javadoc/org/owasp/esapi/class-use/AuthenticationAccountsException.html deleted file mode 100644 index 4e233fc8c..000000000 --- a/javadoc/org/owasp/esapi/class-use/AuthenticationAccountsException.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.AuthenticationAccountsException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.AuthenticationAccountsException

-
-No usage of org.owasp.esapi.AuthenticationAccountsException -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/AuthenticationCredentialsException.html b/javadoc/org/owasp/esapi/class-use/AuthenticationCredentialsException.html deleted file mode 100644 index 1e2ed54d8..000000000 --- a/javadoc/org/owasp/esapi/class-use/AuthenticationCredentialsException.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.AuthenticationCredentialsException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.AuthenticationCredentialsException

-
-No usage of org.owasp.esapi.AuthenticationCredentialsException -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/AuthenticationException.html b/javadoc/org/owasp/esapi/class-use/AuthenticationException.html deleted file mode 100644 index 7acd48aa5..000000000 --- a/javadoc/org/owasp/esapi/class-use/AuthenticationException.html +++ /dev/null @@ -1,468 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.AuthenticationException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.AuthenticationException

-
- - - - - - - - - - - - - -
-Packages that use AuthenticationException
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceReference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of AuthenticationException in org.owasp.esapi
-  -

- - - - - - - - - - - - - - - - - - - - - -
Subclasses of AuthenticationException in org.owasp.esapi
- classAuthenticationAccountsException - -
-          An AuthenticationException should be thrown when anything goes wrong during - login or logout.
- classAuthenticationCredentialsException - -
-          An AuthenticationException should be thrown when anything goes wrong during - login or logout.
- classAuthenticationHostException - -
-          An AuthenticationHostException should be thrown when there is a problem with - the host involved with authentication, particularly if the host changes unexpectedly.
- classAuthenticationLoginException - -
-          An AuthenticationException should be thrown when anything goes wrong during - login or logout.
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi that throw AuthenticationException
- UserAuthenticator.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.
- UserAuthenticator.createUser(java.lang.String accountName, - java.lang.String password1, - java.lang.String password2) - -
-          Creates the user.
- voidAuthenticator.changePassword(User user, - java.lang.String currentPassword, - java.lang.String newPassword, - java.lang.String newPassword2) - -
-          Changes the password for the specified user.
- voidAuthenticator.removeUser(java.lang.String accountName) - -
-          Removes the account.
- voidAuthenticator.verifyAccountNameStrength(java.lang.String accountName) - -
-          Ensures that the account name passes site-specific complexity requirements.
- voidAuthenticator.verifyPasswordStrength(java.lang.String oldPassword, - java.lang.String newPassword) - -
-          Ensures that the password meets site-specific complexity requirements.
- javax.servlet.http.HttpSessionHTTPUtilities.changeSessionIdentifier() - -
-          Invalidate the old session after copying all of its contents to a newly created session with a new session id.
- voidUser.addRole(java.lang.String role) - -
-          Adds a role to an account.
- voidUser.addRoles(java.util.Set newRoles) - -
-          Adds the roles.
- voidUser.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.DateUser.getLastFailedLoginTime() - -
-          Returns the date of the last failed login time for a user.
- voidUser.loginWithPassword(java.lang.String password) - -
-          Login with password.
- voidUser.removeRole(java.lang.String role) - -
-          Removes a role from an account.
- java.lang.StringUser.resetCSRFToken() - -
-          Returns a token to be used as a prevention against CSRF attacks.
- voidUser.setRoles(java.util.Set roles) - -
-          Sets the roles.
-  -

- - - - - -
-Uses of AuthenticationException in org.owasp.esapi.reference
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi.reference that throw AuthenticationException
- voidDefaultUser.addRole(java.lang.String role) - -
-           
- voidDefaultUser.addRoles(java.util.Set newRoles) - -
-           
- voidDefaultUser.changePassword(java.lang.String oldPassword, - java.lang.String newPassword1, - java.lang.String newPassword2) - -
-           
- voidDefaultUser.loginWithPassword(java.lang.String password) - -
-           
- voidDefaultUser.setRoles(java.util.Set roles) - -
-          Sets the roles.
- UserFileBasedAuthenticator.createUser(java.lang.String accountName, - java.lang.String password1, - java.lang.String password2) - -
-           
- voidFileBasedAuthenticator.changePassword(User user, - java.lang.String currentPassword, - java.lang.String newPassword, - java.lang.String newPassword2) - -
-           
- voidFileBasedAuthenticator.removeUser(java.lang.String accountName) - -
-           
- UserFileBasedAuthenticator.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.
- voidFileBasedAuthenticator.verifyAccountNameStrength(java.lang.String newAccountName) - -
-           
- voidFileBasedAuthenticator.verifyPasswordStrength(java.lang.String oldPassword, - java.lang.String newPassword) - -
-           
- javax.servlet.http.HttpSessionDefaultHTTPUtilities.changeSessionIdentifier() - -
-           
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/AuthenticationHostException.html b/javadoc/org/owasp/esapi/class-use/AuthenticationHostException.html deleted file mode 100644 index 9b9a57860..000000000 --- a/javadoc/org/owasp/esapi/class-use/AuthenticationHostException.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.AuthenticationHostException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.AuthenticationHostException

-
-No usage of org.owasp.esapi.AuthenticationHostException -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/AuthenticationLoginException.html b/javadoc/org/owasp/esapi/class-use/AuthenticationLoginException.html deleted file mode 100644 index bb73e741e..000000000 --- a/javadoc/org/owasp/esapi/class-use/AuthenticationLoginException.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.AuthenticationLoginException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.AuthenticationLoginException

-
-No usage of org.owasp.esapi.AuthenticationLoginException -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/Authenticator.html b/javadoc/org/owasp/esapi/class-use/Authenticator.html deleted file mode 100644 index d42404dd9..000000000 --- a/javadoc/org/owasp/esapi/class-use/Authenticator.html +++ /dev/null @@ -1,218 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.Authenticator - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.Authenticator

-
- - - - - - - - - - - - - -
-Packages that use Authenticator
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of Authenticator in org.owasp.esapi
-  -

- - - - - - - - - -
Methods in org.owasp.esapi that return Authenticator
-static AuthenticatorESAPI.authenticator() - -
-           
-  -

- - - - - - - - - -
Methods in org.owasp.esapi with parameters of type Authenticator
-static voidESAPI.setAuthenticator(Authenticator authenticator) - -
-           
-  -

- - - - - -
-Uses of Authenticator in org.owasp.esapi.reference
-  -

- - - - - - - - - -
Classes in org.owasp.esapi.reference that implement Authenticator
- classFileBasedAuthenticator - -
-          Reference implementation of the Authenticator interface.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/AuthenticatorTest.html b/javadoc/org/owasp/esapi/class-use/AuthenticatorTest.html deleted file mode 100644 index cf962d36d..000000000 --- a/javadoc/org/owasp/esapi/class-use/AuthenticatorTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.AuthenticatorTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.AuthenticatorTest

-
-No usage of org.owasp.esapi.AuthenticatorTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/AvailabilityException.html b/javadoc/org/owasp/esapi/class-use/AvailabilityException.html deleted file mode 100644 index e97f13216..000000000 --- a/javadoc/org/owasp/esapi/class-use/AvailabilityException.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.AvailabilityException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.AvailabilityException

-
-No usage of org.owasp.esapi.AvailabilityException -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/CertificateException.html b/javadoc/org/owasp/esapi/class-use/CertificateException.html deleted file mode 100644 index c5170790a..000000000 --- a/javadoc/org/owasp/esapi/class-use/CertificateException.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.CertificateException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.CertificateException

-
-No usage of org.owasp.esapi.CertificateException -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/ESAPI.html b/javadoc/org/owasp/esapi/class-use/ESAPI.html deleted file mode 100644 index eaa77e3cd..000000000 --- a/javadoc/org/owasp/esapi/class-use/ESAPI.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.ESAPI - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.ESAPI

-
-No usage of org.owasp.esapi.ESAPI -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/ESAPITest.html b/javadoc/org/owasp/esapi/class-use/ESAPITest.html deleted file mode 100644 index dd77a6b69..000000000 --- a/javadoc/org/owasp/esapi/class-use/ESAPITest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.ESAPITest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.ESAPITest

-
-No usage of org.owasp.esapi.ESAPITest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/Encoder.html b/javadoc/org/owasp/esapi/class-use/Encoder.html deleted file mode 100644 index 703bef307..000000000 --- a/javadoc/org/owasp/esapi/class-use/Encoder.html +++ /dev/null @@ -1,218 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.Encoder - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.Encoder

-
- - - - - - - - - - - - - -
-Packages that use Encoder
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of Encoder in org.owasp.esapi
-  -

- - - - - - - - - -
Methods in org.owasp.esapi that return Encoder
-static EncoderESAPI.encoder() - -
-           
-  -

- - - - - - - - - -
Methods in org.owasp.esapi with parameters of type Encoder
-static voidESAPI.setEncoder(Encoder encoder) - -
-           
-  -

- - - - - -
-Uses of Encoder in org.owasp.esapi.reference
-  -

- - - - - - - - - -
Classes in org.owasp.esapi.reference that implement Encoder
- classDefaultEncoder - -
-          Reference implementation of the Encoder interface.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/EncoderTest.html b/javadoc/org/owasp/esapi/class-use/EncoderTest.html deleted file mode 100644 index 1a0a7fd33..000000000 --- a/javadoc/org/owasp/esapi/class-use/EncoderTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.EncoderTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.EncoderTest

-
-No usage of org.owasp.esapi.EncoderTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/EncodingException.html b/javadoc/org/owasp/esapi/class-use/EncodingException.html deleted file mode 100644 index ee0a16cf7..000000000 --- a/javadoc/org/owasp/esapi/class-use/EncodingException.html +++ /dev/null @@ -1,227 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.EncodingException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.EncodingException

-
- - - - - - - - - - - - - -
-Packages that use EncodingException
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceReference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of EncodingException in org.owasp.esapi
-  -

- - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi that throw EncodingException
- java.lang.StringEncoder.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.StringEncoder.encodeForURL(java.lang.String input) - -
-          Encode for use in a URL.
- java.lang.StringEncoder.decodeFromURL(java.lang.String input) - -
-          Decode from URL.
-  -

- - - - - -
-Uses of EncodingException in org.owasp.esapi.reference
-  -

- - - - - - - - - - - - - -
Methods in org.owasp.esapi.reference that throw EncodingException
- java.lang.StringDefaultEncoder.encodeForURL(java.lang.String input) - -
-           
- java.lang.StringDefaultEncoder.decodeFromURL(java.lang.String input) - -
-           
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/EncryptedProperties.html b/javadoc/org/owasp/esapi/class-use/EncryptedProperties.html deleted file mode 100644 index a147f58e6..000000000 --- a/javadoc/org/owasp/esapi/class-use/EncryptedProperties.html +++ /dev/null @@ -1,172 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.EncryptedProperties - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.EncryptedProperties

-
- - - - - - - - - -
-Packages that use EncryptedProperties
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of EncryptedProperties in org.owasp.esapi.reference
-  -

- - - - - - - - - -
Classes in org.owasp.esapi.reference that implement EncryptedProperties
- classDefaultEncryptedProperties - -
-          Reference implementation of the EncryptedProperties interface.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/EncryptedPropertiesTest.html b/javadoc/org/owasp/esapi/class-use/EncryptedPropertiesTest.html deleted file mode 100644 index 999e60c4d..000000000 --- a/javadoc/org/owasp/esapi/class-use/EncryptedPropertiesTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.EncryptedPropertiesTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.EncryptedPropertiesTest

-
-No usage of org.owasp.esapi.EncryptedPropertiesTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/EncryptionException.html b/javadoc/org/owasp/esapi/class-use/EncryptionException.html deleted file mode 100644 index 9132be516..000000000 --- a/javadoc/org/owasp/esapi/class-use/EncryptionException.html +++ /dev/null @@ -1,451 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.EncryptionException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.EncryptionException

-
- - - - - - - - - - - - - -
-Packages that use EncryptionException
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceReference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of EncryptionException in org.owasp.esapi
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi that throw EncryptionException
- java.lang.StringAuthenticator.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.StringHTTPUtilities.encryptHiddenField(java.lang.String value) - -
-          Encrypts a hidden field value for use in HTML.
- java.lang.StringHTTPUtilities.encryptQueryString(java.lang.String query) - -
-          Takes a querystring (i.e.
- java.util.MapHTTPUtilities.decryptQueryString(java.lang.String encrypted) - -
-          Takes an encrypted querystring and returns a Map containing the original parameters.
- java.util.MapHTTPUtilities.decryptStateFromCookie() - -
-          Retrieves a map of data from a cookie encrypted with encryptStateInCookie().
- voidHTTPUtilities.encryptStateInCookie(java.util.Map cleartext) - -
-          Stores a Map of data in an encrypted cookie.
- java.lang.StringEncryptedProperties.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.StringEncryptedProperties.setProperty(java.lang.String key, - java.lang.String value) - -
-          Encrypts the plaintext property value and stores the ciphertext value in the encrypted store.
- voidUser.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.
- booleanUser.verifyPassword(java.lang.String password) - -
-          Verify that the supplied password matches the password for this user.
- java.lang.StringRandomizer.getRandomGUID() - -
-          Generates a random GUID.
- java.lang.StringEncryptor.hash(java.lang.String plaintext, - java.lang.String salt) - -
-          Returns a string representation of the hash of the provided plaintext and - salt.
- java.lang.StringEncryptor.encrypt(java.lang.String plaintext) - -
-          Encrypts the provided plaintext and returns a ciphertext string.
- java.lang.StringEncryptor.decrypt(java.lang.String ciphertext) - -
-          Decrypts the provided ciphertext string (encrypted with the encrypt - method) and returns a plaintext string.
- java.lang.StringEncryptor.sign(java.lang.String data) - -
-          Create a digital signature for the provided data and return it in a - string.
- java.lang.StringEncryptor.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.
-  -

- - - - - -
-Uses of EncryptionException in org.owasp.esapi.reference
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi.reference that throw EncryptionException
- java.lang.StringDefaultEncryptedProperties.getProperty(java.lang.String key) - -
-           
- java.lang.StringDefaultEncryptedProperties.setProperty(java.lang.String key, - java.lang.String value) - -
-           
- voidDefaultUser.changePassword(java.lang.String oldPassword, - java.lang.String newPassword1, - java.lang.String newPassword2) - -
-           
- java.lang.StringFileBasedAuthenticator.hashPassword(java.lang.String password, - java.lang.String accountName) - -
-           
- java.util.MapDefaultHTTPUtilities.decryptQueryString(java.lang.String encrypted) - -
-           
- java.util.MapDefaultHTTPUtilities.decryptStateFromCookie() - -
-           
- java.lang.StringDefaultHTTPUtilities.encryptHiddenField(java.lang.String value) - -
-           
- java.lang.StringDefaultHTTPUtilities.encryptQueryString(java.lang.String query) - -
-           
- voidDefaultHTTPUtilities.encryptStateInCookie(java.util.Map cleartext) - -
-           
- java.lang.StringDefaultRandomizer.getRandomGUID() - -
-           
- java.lang.StringJSEEncryptor.hash(java.lang.String plaintext, - java.lang.String salt) - -
-          Hashes the data using the specified algorithm and the Java MessageDigest class.
- java.lang.StringJSEEncryptor.encrypt(java.lang.String plaintext) - -
-           
- java.lang.StringJSEEncryptor.decrypt(java.lang.String ciphertext) - -
-           
- java.lang.StringJSEEncryptor.sign(java.lang.String data) - -
-           
- java.lang.StringJSEEncryptor.unseal(java.lang.String seal) - -
-           
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/Encryptor.html b/javadoc/org/owasp/esapi/class-use/Encryptor.html deleted file mode 100644 index a9b0cf08d..000000000 --- a/javadoc/org/owasp/esapi/class-use/Encryptor.html +++ /dev/null @@ -1,218 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.Encryptor - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.Encryptor

-
- - - - - - - - - - - - - -
-Packages that use Encryptor
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of Encryptor in org.owasp.esapi
-  -

- - - - - - - - - -
Methods in org.owasp.esapi that return Encryptor
-static EncryptorESAPI.encryptor() - -
-           
-  -

- - - - - - - - - -
Methods in org.owasp.esapi with parameters of type Encryptor
-static voidESAPI.setEncryptor(Encryptor encryptor) - -
-           
-  -

- - - - - -
-Uses of Encryptor in org.owasp.esapi.reference
-  -

- - - - - - - - - -
Classes in org.owasp.esapi.reference that implement Encryptor
- classJavaEncryptor - -
-          Reference implementation of the Encryptor interface.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/EncryptorTest.html b/javadoc/org/owasp/esapi/class-use/EncryptorTest.html deleted file mode 100644 index 6e968ed38..000000000 --- a/javadoc/org/owasp/esapi/class-use/EncryptorTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.EncryptorTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.EncryptorTest

-
-No usage of org.owasp.esapi.EncryptorTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/EnterpriseSecurityException.html b/javadoc/org/owasp/esapi/class-use/EnterpriseSecurityException.html deleted file mode 100644 index 060d090dc..000000000 --- a/javadoc/org/owasp/esapi/class-use/EnterpriseSecurityException.html +++ /dev/null @@ -1,299 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.EnterpriseSecurityException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.EnterpriseSecurityException

-
- - - - - - - - - -
-Packages that use EnterpriseSecurityException
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
-  -

- - - - - -
-Uses of EnterpriseSecurityException in org.owasp.esapi
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Subclasses of EnterpriseSecurityException in org.owasp.esapi
- classAccessControlException - -
-          An AccessControlException should be thrown when a user attempts to access a - resource that they are not authorized for.
- classAuthenticationAccountsException - -
-          An AuthenticationException should be thrown when anything goes wrong during - login or logout.
- classAuthenticationCredentialsException - -
-          An AuthenticationException should be thrown when anything goes wrong during - login or logout.
- classAuthenticationException - -
-          An AuthenticationException should be thrown when anything goes wrong during - login or logout.
- classAuthenticationHostException - -
-          An AuthenticationHostException should be thrown when there is a problem with - the host involved with authentication, particularly if the host changes unexpectedly.
- classAuthenticationLoginException - -
-          An AuthenticationException should be thrown when anything goes wrong during - login or logout.
- classAvailabilityException - -
-          An AvailabilityException should be thrown when the availability of a limited - resource is in jeopardy.
- classCertificateException - -
-          A CertificateException should be thrown for any problems that arise during - processing of digital certificates.
- classEncodingException - -
-          An ExecutorException should be thrown for any problems that occur when - encoding or decoding data.
- classEncryptionException - -
-          An EncryptionException should be thrown for any problems related to - encryption, hashing, or digital signatures.
- classExecutorException - -
-          An ExecutorException should be thrown for any problems that arise during the - execution of a system executable.
- classIntegrityException - -
-          An AvailabilityException should be thrown when the availability of a limited - resource is in jeopardy.
- classValidationAvailabilityException - -
-          FIXME: DOC.
- classValidationException - -
-          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.
- classValidationUploadException - -
-          FIXME: DOC.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/Executor.html b/javadoc/org/owasp/esapi/class-use/Executor.html deleted file mode 100644 index 26032cfbb..000000000 --- a/javadoc/org/owasp/esapi/class-use/Executor.html +++ /dev/null @@ -1,218 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.Executor - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.Executor

-
- - - - - - - - - - - - - -
-Packages that use Executor
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of Executor in org.owasp.esapi
-  -

- - - - - - - - - -
Methods in org.owasp.esapi that return Executor
-static ExecutorESAPI.executor() - -
-           
-  -

- - - - - - - - - -
Methods in org.owasp.esapi with parameters of type Executor
-static voidESAPI.setExecutor(Executor executor) - -
-           
-  -

- - - - - -
-Uses of Executor in org.owasp.esapi.reference
-  -

- - - - - - - - - -
Classes in org.owasp.esapi.reference that implement Executor
- classDefaultExecutor - -
-          Reference implementation of the Executor interface.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/ExecutorException.html b/javadoc/org/owasp/esapi/class-use/ExecutorException.html deleted file mode 100644 index 606047c15..000000000 --- a/javadoc/org/owasp/esapi/class-use/ExecutorException.html +++ /dev/null @@ -1,210 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.ExecutorException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.ExecutorException

-
- - - - - - - - - - - - - -
-Packages that use ExecutorException
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceReference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of ExecutorException in org.owasp.esapi
-  -

- - - - - - - - - -
Methods in org.owasp.esapi that throw ExecutorException
- java.lang.StringExecutor.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.
-  -

- - - - - -
-Uses of ExecutorException in org.owasp.esapi.reference
-  -

- - - - - - - - - -
Methods in org.owasp.esapi.reference that throw ExecutorException
- java.lang.StringDefaultExecutor.executeSystemCommand(java.io.File executable, - java.util.List params, - java.io.File workdir, - int timeoutSeconds) - -
-           
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/ExecutorTest.html b/javadoc/org/owasp/esapi/class-use/ExecutorTest.html deleted file mode 100644 index 8d52cd087..000000000 --- a/javadoc/org/owasp/esapi/class-use/ExecutorTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.ExecutorTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.ExecutorTest

-
-No usage of org.owasp.esapi.ExecutorTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/HTTPUtilities.html b/javadoc/org/owasp/esapi/class-use/HTTPUtilities.html deleted file mode 100644 index b28869ca2..000000000 --- a/javadoc/org/owasp/esapi/class-use/HTTPUtilities.html +++ /dev/null @@ -1,218 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.HTTPUtilities - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.HTTPUtilities

-
- - - - - - - - - - - - - -
-Packages that use HTTPUtilities
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of HTTPUtilities in org.owasp.esapi
-  -

- - - - - - - - - -
Methods in org.owasp.esapi that return HTTPUtilities
-static HTTPUtilitiesESAPI.httpUtilities() - -
-           
-  -

- - - - - - - - - -
Methods in org.owasp.esapi with parameters of type HTTPUtilities
-static voidESAPI.setHttpUtilities(HTTPUtilities httpUtilities) - -
-           
-  -

- - - - - -
-Uses of HTTPUtilities in org.owasp.esapi.reference
-  -

- - - - - - - - - -
Classes in org.owasp.esapi.reference that implement HTTPUtilities
- classDefaultHTTPUtilities - -
-          Reference implementation of the HTTPUtilities interface.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/HTTPUtilitiesTest.html b/javadoc/org/owasp/esapi/class-use/HTTPUtilitiesTest.html deleted file mode 100644 index 44710f825..000000000 --- a/javadoc/org/owasp/esapi/class-use/HTTPUtilitiesTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.HTTPUtilitiesTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.HTTPUtilitiesTest

-
-No usage of org.owasp.esapi.HTTPUtilitiesTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/IntegrityException.html b/javadoc/org/owasp/esapi/class-use/IntegrityException.html deleted file mode 100644 index 5b9e70df1..000000000 --- a/javadoc/org/owasp/esapi/class-use/IntegrityException.html +++ /dev/null @@ -1,204 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.IntegrityException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.IntegrityException

-
- - - - - - - - - - - - - -
-Packages that use IntegrityException
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceReference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of IntegrityException in org.owasp.esapi
-  -

- - - - - - - - - -
Methods in org.owasp.esapi that throw IntegrityException
- java.lang.StringEncryptor.seal(java.lang.String data, - long timestamp) - -
-          Creates a seal that binds a set of data and includes an expiration timestamp.
-  -

- - - - - -
-Uses of IntegrityException in org.owasp.esapi.reference
-  -

- - - - - - - - - -
Methods in org.owasp.esapi.reference that throw IntegrityException
- java.lang.StringJSEEncryptor.seal(java.lang.String data, - long expiration) - -
-           
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/IntrusionDetector.html b/javadoc/org/owasp/esapi/class-use/IntrusionDetector.html deleted file mode 100644 index 605bfa46a..000000000 --- a/javadoc/org/owasp/esapi/class-use/IntrusionDetector.html +++ /dev/null @@ -1,218 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.IntrusionDetector - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.IntrusionDetector

-
- - - - - - - - - - - - - -
-Packages that use IntrusionDetector
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of IntrusionDetector in org.owasp.esapi
-  -

- - - - - - - - - -
Methods in org.owasp.esapi that return IntrusionDetector
-static IntrusionDetectorESAPI.intrusionDetector() - -
-           
-  -

- - - - - - - - - -
Methods in org.owasp.esapi with parameters of type IntrusionDetector
-static voidESAPI.setIntrusionDetector(IntrusionDetector intrusionDetector) - -
-           
-  -

- - - - - -
-Uses of IntrusionDetector in org.owasp.esapi.reference
-  -

- - - - - - - - - -
Classes in org.owasp.esapi.reference that implement IntrusionDetector
- classDefaultIntrusionDetector - -
-          Reference implementation of the IntrusionDetector interface.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/IntrusionDetectorTest.html b/javadoc/org/owasp/esapi/class-use/IntrusionDetectorTest.html deleted file mode 100644 index 4ca292023..000000000 --- a/javadoc/org/owasp/esapi/class-use/IntrusionDetectorTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.IntrusionDetectorTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.IntrusionDetectorTest

-
-No usage of org.owasp.esapi.IntrusionDetectorTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/IntrusionException.html b/javadoc/org/owasp/esapi/class-use/IntrusionException.html deleted file mode 100644 index 2b11a99da..000000000 --- a/javadoc/org/owasp/esapi/class-use/IntrusionException.html +++ /dev/null @@ -1,925 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.IntrusionException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.IntrusionException

-
- - - - - - - - - - - - - -
-Packages that use IntrusionException
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceReference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of IntrusionException in org.owasp.esapi
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi that throw IntrusionException
- voidHTTPUtilities.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.
- voidIntrusionDetector.addException(java.lang.Exception exception) - -
-          Adds the exception to the IntrusionDetector.
- voidIntrusionDetector.addEvent(java.lang.String eventName) - -
-          Adds the event to the IntrusionDetector.
- booleanValidator.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.StringValidator.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.
- booleanValidator.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.DateValidator.getValidDate(java.lang.String context, - java.lang.String input, - java.text.DateFormat format, - boolean allowNull) - -
-          Returns a valid date as a Date.
- booleanValidator.isValidSafeHTML(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-          Returns true if input is "safe" HTML.
- booleanValidator.isValidCreditCard(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns true if input is a valid credit card.
- java.lang.StringValidator.getValidCreditCard(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated credit card number as a String.
- booleanValidator.isValidDirectoryPath(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns true if input is a valid directory path.
- java.lang.StringValidator.getValidDirectoryPath(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated directory path as a String.
- booleanValidator.isValidFileName(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns true if input is a valid file name.
- java.lang.StringValidator.getValidFileName(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated file name as a String.
- booleanValidator.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.DoubleValidator.getValidNumber(java.lang.String context, - java.lang.String input, - long minValue, - long maxValue, - boolean allowNull) - -
-          Returns a validated number as a double.
- booleanValidator.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.IntegerValidator.getValidInteger(java.lang.String context, - java.lang.String input, - int minValue, - int maxValue, - boolean allowNull) - -
-          Returns a validated integer as an int.
- booleanValidator.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.DoubleValidator.getValidDouble(java.lang.String context, - java.lang.String input, - double minValue, - double maxValue, - boolean allowNull) - -
-          Returns a validated real number as a double.
- booleanValidator.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.
- booleanValidator.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.
- voidValidator.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.
- booleanValidator.isValidHTTPRequest() - -
-          Validate the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed - characters.
- voidValidator.assertIsValidHTTPRequest() - -
-          Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed - characters.
- booleanValidator.isValidListItem(java.lang.String context, - java.lang.String input, - java.util.List list) - -
-          Returns true if input is a valid list item.
- java.lang.StringValidator.getValidListItem(java.lang.String context, - java.lang.String input, - java.util.List list) - -
-          Returns the list item that exactly matches the canonicalized input.
- booleanValidator.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.
- voidValidator.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.
- booleanValidator.isValidPrintable(java.lang.String context, - byte[] input, - int maxLength, - boolean allowNull) - -
-          Returns true if input is valid printable ASCII characters.
- booleanValidator.isValidPrintable(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-          Returns true if input is valid printable ASCII characters (32-126).
- booleanValidator.isValidRedirectLocation(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns true if input is a valid redirect location.
-  -

- - - - - -
-Uses of IntrusionException in org.owasp.esapi.reference
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi.reference that throw IntrusionException
- booleanDefaultValidator.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.StringDefaultValidator.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.
- booleanDefaultValidator.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.DateDefaultValidator.getValidDate(java.lang.String context, - java.lang.String input, - java.text.DateFormat format, - boolean allowNull) - -
-           
- booleanDefaultValidator.isValidSafeHTML(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-           
- java.lang.StringDefaultValidator.getValidSafeHTML(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-           
- booleanDefaultValidator.isValidCreditCard(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-           
- java.lang.StringDefaultValidator.getValidCreditCard(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated credit card number as a String.
- booleanDefaultValidator.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.StringDefaultValidator.getValidDirectoryPath(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated directory path as a String.
- booleanDefaultValidator.isValidFileName(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns true if input is a valid file name.
- java.lang.StringDefaultValidator.getValidFileName(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated file name as a String.
- booleanDefaultValidator.isValidNumber(java.lang.String context, - java.lang.String input, - long minValue, - long maxValue, - boolean allowNull) - -
-           
- java.lang.DoubleDefaultValidator.getValidNumber(java.lang.String context, - java.lang.String input, - long minValue, - long maxValue, - boolean allowNull) - -
-          Returns a validated number as a double.
- booleanDefaultValidator.isValidDouble(java.lang.String context, - java.lang.String input, - double minValue, - double maxValue, - boolean allowNull) - -
-           
- java.lang.DoubleDefaultValidator.getValidDouble(java.lang.String context, - java.lang.String input, - double minValue, - double maxValue, - boolean allowNull) - -
-          Returns a validated number as a double.
- booleanDefaultValidator.isValidInteger(java.lang.String context, - java.lang.String input, - int minValue, - int maxValue, - boolean allowNull) - -
-           
- java.lang.IntegerDefaultValidator.getValidInteger(java.lang.String context, - java.lang.String input, - int minValue, - int maxValue, - boolean allowNull) - -
-          Returns a validated number as a double.
- booleanDefaultValidator.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.
- booleanDefaultValidator.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.
- voidDefaultValidator.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.
- booleanDefaultValidator.isValidHTTPRequest() - -
-          Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed - characters.
- booleanDefaultValidator.isValidHTTPRequest(javax.servlet.http.HttpServletRequest request) - -
-          Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed - characters.
- voidDefaultValidator.assertIsValidHTTPRequest() - -
-          Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed - characters.
- voidDefaultValidator.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.StringDefaultValidator.getValidListItem(java.lang.String context, - java.lang.String input, - java.util.List list) - -
-          Returns the list item that exactly matches the canonicalized input.
- voidDefaultValidator.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.
- booleanDefaultValidator.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.
- booleanDefaultValidator.isValidPrintable(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-           
- java.lang.StringDefaultValidator.getValidPrintable(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-          Returns canonicalized and validated printable characters as a String.
- booleanDefaultValidator.isValidRedirectLocation(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns true if input is a valid redirect location.
- java.lang.StringDefaultValidator.getValidRedirectLocation(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated redirect location as a String.
- voidDefaultIntrusionDetector.addEvent(java.lang.String eventName) - -
-          Adds the event to the IntrusionDetector.
- voidDefaultHTTPUtilities.verifyCSRFToken() - -
-           
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/JavaLogFactory.html b/javadoc/org/owasp/esapi/class-use/JavaLogFactory.html deleted file mode 100644 index 44e9d0e00..000000000 --- a/javadoc/org/owasp/esapi/class-use/JavaLogFactory.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.JavaLogFactory - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.JavaLogFactory

-
-No usage of org.owasp.esapi.JavaLogFactory -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/LogFactory.html b/javadoc/org/owasp/esapi/class-use/LogFactory.html deleted file mode 100644 index 064200f09..000000000 --- a/javadoc/org/owasp/esapi/class-use/LogFactory.html +++ /dev/null @@ -1,202 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.LogFactory - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.LogFactory

-
- - - - - - - - - - - - - -
-Packages that use LogFactory
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of LogFactory in org.owasp.esapi
-  -

- - - - - - - - - -
Methods in org.owasp.esapi with parameters of type LogFactory
-static voidESAPI.setLogFactory(LogFactory factory) - -
-           
-  -

- - - - - -
-Uses of LogFactory in org.owasp.esapi.reference
-  -

- - - - - - - - - -
Classes in org.owasp.esapi.reference that implement LogFactory
- classJavaLogFactory - -
-          Reference implementation of the LogFactory and Logger interfaces.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/Logger.html b/javadoc/org/owasp/esapi/class-use/Logger.html deleted file mode 100644 index e32f321dd..000000000 --- a/javadoc/org/owasp/esapi/class-use/Logger.html +++ /dev/null @@ -1,298 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.Logger - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.Logger

-
- - - - - - - - - - - - - -
-Packages that use Logger
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of Logger in org.owasp.esapi
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi that return Logger
- LoggerLogFactory.getLogger(java.lang.String name) - -
-           
- LoggerLogFactory.getLogger(java.lang.Class clazz) - -
-           
-static LoggerESAPI.getLogger(java.lang.Class clazz) - -
-           
-static LoggerESAPI.getLogger(java.lang.String name) - -
-           
-static LoggerESAPI.log() - -
-           
-  -

- - - - - - - - - - - - - -
Methods in org.owasp.esapi with parameters of type Logger
- voidHTTPUtilities.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.
- voidHTTPUtilities.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.
-  -

- - - - - -
-Uses of Logger in org.owasp.esapi.reference
-  -

- - - - - - - - - - - - - -
Methods in org.owasp.esapi.reference that return Logger
- LoggerJavaLogFactory.getLogger(java.lang.Class clazz) - -
-           
- LoggerJavaLogFactory.getLogger(java.lang.String name) - -
-           
-  -

- - - - - - - - - - - - - -
Methods in org.owasp.esapi.reference with parameters of type Logger
- voidDefaultHTTPUtilities.logHTTPRequest(javax.servlet.http.HttpServletRequest request, - Logger logger) - -
-           
- voidDefaultHTTPUtilities.logHTTPRequest(javax.servlet.http.HttpServletRequest request, - Logger logger, - java.util.List parameterNamesToObfuscate) - -
-          Formats an HTTP request into a log suitable string.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/LoggerTest.html b/javadoc/org/owasp/esapi/class-use/LoggerTest.html deleted file mode 100644 index f7514e0b1..000000000 --- a/javadoc/org/owasp/esapi/class-use/LoggerTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.LoggerTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.LoggerTest

-
-No usage of org.owasp.esapi.LoggerTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/RandomAccessReferenceMap.html b/javadoc/org/owasp/esapi/class-use/RandomAccessReferenceMap.html deleted file mode 100644 index c41ebb55c..000000000 --- a/javadoc/org/owasp/esapi/class-use/RandomAccessReferenceMap.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.RandomAccessReferenceMap - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.RandomAccessReferenceMap

-
-No usage of org.owasp.esapi.RandomAccessReferenceMap -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/Randomizer.html b/javadoc/org/owasp/esapi/class-use/Randomizer.html deleted file mode 100644 index 41e28fd1f..000000000 --- a/javadoc/org/owasp/esapi/class-use/Randomizer.html +++ /dev/null @@ -1,218 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.Randomizer - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.Randomizer

-
- - - - - - - - - - - - - -
-Packages that use Randomizer
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of Randomizer in org.owasp.esapi
-  -

- - - - - - - - - -
Methods in org.owasp.esapi that return Randomizer
-static RandomizerESAPI.randomizer() - -
-           
-  -

- - - - - - - - - -
Methods in org.owasp.esapi with parameters of type Randomizer
-static voidESAPI.setRandomizer(Randomizer randomizer) - -
-           
-  -

- - - - - -
-Uses of Randomizer in org.owasp.esapi.reference
-  -

- - - - - - - - - -
Classes in org.owasp.esapi.reference that implement Randomizer
- classDefaultRandomizer - -
-          Reference implementation of the Randomizer interface.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/RandomizerTest.html b/javadoc/org/owasp/esapi/class-use/RandomizerTest.html deleted file mode 100644 index 1e3186192..000000000 --- a/javadoc/org/owasp/esapi/class-use/RandomizerTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.RandomizerTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.RandomizerTest

-
-No usage of org.owasp.esapi.RandomizerTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/SafeFile.html b/javadoc/org/owasp/esapi/class-use/SafeFile.html deleted file mode 100644 index 29fe3aa82..000000000 --- a/javadoc/org/owasp/esapi/class-use/SafeFile.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.SafeFile - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.SafeFile

-
-No usage of org.owasp.esapi.SafeFile -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/SafeFileTest.html b/javadoc/org/owasp/esapi/class-use/SafeFileTest.html deleted file mode 100644 index ae66ab786..000000000 --- a/javadoc/org/owasp/esapi/class-use/SafeFileTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.SafeFileTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.SafeFileTest

-
-No usage of org.owasp.esapi.SafeFileTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/SecurityConfiguration.Threshold.html b/javadoc/org/owasp/esapi/class-use/SecurityConfiguration.Threshold.html deleted file mode 100644 index f813e6969..000000000 --- a/javadoc/org/owasp/esapi/class-use/SecurityConfiguration.Threshold.html +++ /dev/null @@ -1,202 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.SecurityConfiguration.Threshold - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.SecurityConfiguration.Threshold

-
- - - - - - - - - - - - - -
-Packages that use SecurityConfiguration.Threshold
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of SecurityConfiguration.Threshold in org.owasp.esapi
-  -

- - - - - - - - - -
Methods in org.owasp.esapi that return SecurityConfiguration.Threshold
- SecurityConfiguration.ThresholdSecurityConfiguration.getQuota(java.lang.String eventName) - -
-          Gets an intrusion detection Quota.
-  -

- - - - - -
-Uses of SecurityConfiguration.Threshold in org.owasp.esapi.reference
-  -

- - - - - - - - - -
Methods in org.owasp.esapi.reference that return SecurityConfiguration.Threshold
- SecurityConfiguration.ThresholdDefaultSecurityConfiguration.getQuota(java.lang.String eventName) - -
-           
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/SecurityConfiguration.html b/javadoc/org/owasp/esapi/class-use/SecurityConfiguration.html deleted file mode 100644 index 2529a0b50..000000000 --- a/javadoc/org/owasp/esapi/class-use/SecurityConfiguration.html +++ /dev/null @@ -1,218 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.SecurityConfiguration - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.SecurityConfiguration

-
- - - - - - - - - - - - - -
-Packages that use SecurityConfiguration
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of SecurityConfiguration in org.owasp.esapi
-  -

- - - - - - - - - -
Methods in org.owasp.esapi that return SecurityConfiguration
-static SecurityConfigurationESAPI.securityConfiguration() - -
-           
-  -

- - - - - - - - - -
Methods in org.owasp.esapi with parameters of type SecurityConfiguration
-static voidESAPI.setSecurityConfiguration(SecurityConfiguration securityConfiguration) - -
-           
-  -

- - - - - -
-Uses of SecurityConfiguration in org.owasp.esapi.reference
-  -

- - - - - - - - - -
Classes in org.owasp.esapi.reference that implement SecurityConfiguration
- classDefaultSecurityConfiguration - -
-          The SecurityConfiguration manages all the settings used by the ESAPI in a single place.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/StringUtilities.html b/javadoc/org/owasp/esapi/class-use/StringUtilities.html deleted file mode 100644 index 968c1ecd2..000000000 --- a/javadoc/org/owasp/esapi/class-use/StringUtilities.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.StringUtilities - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.StringUtilities

-
-No usage of org.owasp.esapi.StringUtilities -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/Threshold.html b/javadoc/org/owasp/esapi/class-use/Threshold.html deleted file mode 100644 index 32cba24d9..000000000 --- a/javadoc/org/owasp/esapi/class-use/Threshold.html +++ /dev/null @@ -1,202 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.Threshold - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.Threshold

-
- - - - - - - - - - - - - -
-Packages that use Threshold
org.owasp.esapiReference implementations of the ESAPI interfaces. 
org.owasp.esapi.interfacesA set of interfaces modeling the most important security functions to -enterprise web applications. 
-  -

- - - - - -
-Uses of Threshold in org.owasp.esapi
-  -

- - - - - - - - - -
Methods in org.owasp.esapi that return Threshold
- ThresholdSecurityConfiguration.getQuota(java.lang.String eventName) - -
-           
-  -

- - - - - -
-Uses of Threshold in org.owasp.esapi.interfaces
-  -

- - - - - - - - - -
Methods in org.owasp.esapi.interfaces that return Threshold
- ThresholdISecurityConfiguration.getQuota(java.lang.String eventName) - -
-          Gets an intrusion detection Quota.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/User.html b/javadoc/org/owasp/esapi/class-use/User.html deleted file mode 100644 index 834b90ebe..000000000 --- a/javadoc/org/owasp/esapi/class-use/User.html +++ /dev/null @@ -1,397 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.User - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.User

-
- - - - - - - - - - - - - -
-Packages that use User
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of User in org.owasp.esapi
-  -

- - - - - - - - - -
Fields in org.owasp.esapi declared as User
-static UserUser.ANONYMOUS - -
-          The ANONYMOUS user is used to represent an unidentified user.
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi that return User
- UserAuthenticator.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.
- UserAuthenticator.createUser(java.lang.String accountName, - java.lang.String password1, - java.lang.String password2) - -
-          Creates a new User with the information provided.
- UserAuthenticator.getUser(long accountId) - -
-          Returns the User matching the provided accountId.
- UserAuthenticator.getUser(java.lang.String accountName) - -
-          Returns the User matching the provided accountName.
- UserAuthenticator.getCurrentUser() - -
-          Returns the currently logged in User.
-  -

- - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi with parameters of type User
- booleanAuthenticator.verifyPassword(User user, - java.lang.String password) - -
-          Verify that the supplied password matches the password for this user.
- java.lang.StringAuthenticator.generateStrongPassword(User user, - java.lang.String oldPassword) - -
-          Generate strong password that takes into account the user's information and old password.
- voidAuthenticator.changePassword(User user, - java.lang.String currentPassword, - java.lang.String newPassword, - java.lang.String newPassword2) - -
-          Changes the password for the specified user.
- voidAuthenticator.setCurrentUser(User user) - -
-          Sets the currently logged in User.
-  -

- - - - - -
-Uses of User in org.owasp.esapi.reference
-  -

- - - - - - - - - -
Classes in org.owasp.esapi.reference that implement User
- classDefaultUser - -
-          Reference implementation of the User interface.
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi.reference that return User
- UserFileBasedAuthenticator.createUser(java.lang.String accountName, - java.lang.String password1, - java.lang.String password2) - -
-           
- UserFileBasedAuthenticator.getCurrentUser() - -
-           
- UserFileBasedAuthenticator.getUser(long accountId) - -
-          Gets the user object with the matching account name or null if there is no match.
- UserFileBasedAuthenticator.getUser(java.lang.String accountName) - -
-          Gets the user object with the matching account name or null if there is no match.
- UserFileBasedAuthenticator.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.
-  -

- - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi.reference with parameters of type User
- voidFileBasedAuthenticator.changePassword(User user, - java.lang.String currentPassword, - java.lang.String newPassword, - java.lang.String newPassword2) - -
-           
- booleanFileBasedAuthenticator.verifyPassword(User user, - java.lang.String password) - -
-           
- java.lang.StringFileBasedAuthenticator.generateStrongPassword(User user, - java.lang.String oldPassword) - -
-           
- voidFileBasedAuthenticator.setCurrentUser(User user) - -
-           
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/UserTest.html b/javadoc/org/owasp/esapi/class-use/UserTest.html deleted file mode 100644 index 339cd9810..000000000 --- a/javadoc/org/owasp/esapi/class-use/UserTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.UserTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.UserTest

-
-No usage of org.owasp.esapi.UserTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/ValidationAvailabilityException.html b/javadoc/org/owasp/esapi/class-use/ValidationAvailabilityException.html deleted file mode 100644 index c18a4957b..000000000 --- a/javadoc/org/owasp/esapi/class-use/ValidationAvailabilityException.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.ValidationAvailabilityException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.ValidationAvailabilityException

-
-No usage of org.owasp.esapi.ValidationAvailabilityException -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/ValidationErrorList.html b/javadoc/org/owasp/esapi/class-use/ValidationErrorList.html deleted file mode 100644 index 622a00ede..000000000 --- a/javadoc/org/owasp/esapi/class-use/ValidationErrorList.html +++ /dev/null @@ -1,571 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.ValidationErrorList - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.ValidationErrorList

-
- - - - - - - - - - - - - -
-Packages that use ValidationErrorList
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of ValidationErrorList in org.owasp.esapi
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi with parameters of type ValidationErrorList
- java.lang.StringValidator.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.DateValidator.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.StringValidator.getValidSafeHTML(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull, - ValidationErrorList errorList) - -
-          Returns canonicalized and validated "safe" HTML.
- java.lang.StringValidator.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.StringValidator.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.StringValidator.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.DoubleValidator.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.IntegerValidator.getValidInteger(java.lang.String context, - java.lang.String input, - int minValue, - int maxValue, - boolean allowNull, - ValidationErrorList errorList) - -
-          Returns a validated integer.
- java.lang.DoubleValidator.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.
- voidValidator.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.StringValidator.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.
- voidValidator.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.StringValidator.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.StringValidator.getValidRedirectLocation(java.lang.String context, - java.lang.String input, - boolean allowNull, - ValidationErrorList errorList) - -
-          Returns a canonicalized and validated redirect location as a String.
-  -

- - - - - -
-Uses of ValidationErrorList in org.owasp.esapi.reference
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi.reference with parameters of type ValidationErrorList
- java.lang.StringDefaultValidator.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.util.DateDefaultValidator.getValidDate(java.lang.String context, - java.lang.String input, - java.text.DateFormat format, - boolean allowNull, - ValidationErrorList errors) - -
-           
- java.lang.StringDefaultValidator.getValidSafeHTML(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull, - ValidationErrorList errors) - -
-          ValidationErrorList variant of getValidSafeHTML
- java.lang.StringDefaultValidator.getValidCreditCard(java.lang.String context, - java.lang.String input, - boolean allowNull, - ValidationErrorList errors) - -
-          ValidationErrorList variant of getValidCreditCard
- java.lang.StringDefaultValidator.getValidDirectoryPath(java.lang.String context, - java.lang.String input, - boolean allowNull, - ValidationErrorList errors) - -
-          ValidationErrorList variant of getValidDirectoryPath
- java.lang.StringDefaultValidator.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.DoubleDefaultValidator.getValidNumber(java.lang.String context, - java.lang.String input, - long minValue, - long maxValue, - boolean allowNull, - ValidationErrorList errors) - -
-           
- java.lang.DoubleDefaultValidator.getValidDouble(java.lang.String context, - java.lang.String input, - double minValue, - double maxValue, - boolean allowNull, - ValidationErrorList errors) - -
-           
- java.lang.IntegerDefaultValidator.getValidInteger(java.lang.String context, - java.lang.String input, - int minValue, - int maxValue, - boolean allowNull, - ValidationErrorList errors) - -
-           
- byte[]DefaultValidator.getValidFileContent(java.lang.String context, - byte[] input, - int maxBytes, - boolean allowNull, - ValidationErrorList errors) - -
-           
- voidDefaultValidator.assertValidFileUpload(java.lang.String context, - java.lang.String filepath, - java.lang.String filename, - byte[] content, - int maxBytes, - boolean allowNull, - ValidationErrorList errors) - -
-          ValidationErrorList variant of assertValidFileUpload
- java.lang.StringDefaultValidator.getValidListItem(java.lang.String context, - java.lang.String input, - java.util.List list, - ValidationErrorList errors) - -
-          ValidationErrorList variant of getValidListItem
- voidDefaultValidator.assertIsValidHTTPRequestParameterSet(java.lang.String context, - java.util.Set required, - java.util.Set optional, - ValidationErrorList errors) - -
-          ValidationErrorList variant of assertIsValidHTTPRequestParameterSet
- byte[]DefaultValidator.getValidPrintable(java.lang.String context, - byte[] input, - int maxLength, - boolean allowNull, - ValidationErrorList errors) - -
-          ValidationErrorList variant of getValidPrintable
- java.lang.StringDefaultValidator.getValidPrintable(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull, - ValidationErrorList errors) - -
-          ValidationErrorList variant of getValidPrintable
- java.lang.StringDefaultValidator.getValidRedirectLocation(java.lang.String context, - java.lang.String input, - boolean allowNull, - ValidationErrorList errors) - -
-          ValidationErrorList variant of getValidRedirectLocation
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/ValidationException.html b/javadoc/org/owasp/esapi/class-use/ValidationException.html deleted file mode 100644 index 9b07763e3..000000000 --- a/javadoc/org/owasp/esapi/class-use/ValidationException.html +++ /dev/null @@ -1,693 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.ValidationException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.ValidationException

-
- - - - - - - - - - - - - -
-Packages that use ValidationException
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceReference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of ValidationException in org.owasp.esapi
-  -

- - - - - - - - - - - - - -
Subclasses of ValidationException in org.owasp.esapi
- classValidationAvailabilityException - -
-          FIXME: DOC.
- classValidationUploadException - -
-          FIXME: DOC.
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi that throw ValidationException
- voidHTTPUtilities.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.
- voidHTTPUtilities.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.ListHTTPUtilities.getSafeFileUploads(java.io.File tempDir, - java.io.File finalDir) - -
-          Extract uploaded files from a multipart HTTP requests.
- java.lang.StringValidator.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.DateValidator.getValidDate(java.lang.String context, - java.lang.String input, - java.text.DateFormat format, - boolean allowNull) - -
-          Returns a valid date as a Date.
- java.lang.StringValidator.getValidSafeHTML(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-          Returns canonicalized and validated "safe" HTML.
- java.lang.StringValidator.getValidCreditCard(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated credit card number as a String.
- java.lang.StringValidator.getValidDirectoryPath(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated directory path as a String.
- java.lang.StringValidator.getValidFileName(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated file name as a String.
- java.lang.DoubleValidator.getValidNumber(java.lang.String context, - java.lang.String input, - long minValue, - long maxValue, - boolean allowNull) - -
-          Returns a validated number as a double.
- java.lang.IntegerValidator.getValidInteger(java.lang.String context, - java.lang.String input, - int minValue, - int maxValue, - boolean allowNull) - -
-          Returns a validated integer as an int.
- java.lang.DoubleValidator.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.
- voidValidator.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.
- voidValidator.assertIsValidHTTPRequest() - -
-          Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed - characters.
- java.lang.StringValidator.getValidListItem(java.lang.String context, - java.lang.String input, - java.util.List list) - -
-          Returns the list item that exactly matches the canonicalized input.
- voidValidator.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.StringValidator.getValidPrintable(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-          Returns canonicalized and validated printable characters as a String.
- java.lang.StringValidator.getValidRedirectLocation(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated redirect location as a String.
- java.lang.StringValidator.safeReadLine(java.io.InputStream inputStream, - int maxLength) - -
-          Reads from an input stream until end-of-line or a maximum number of - characters.
-  -

- - - - - -
-Uses of ValidationException in org.owasp.esapi.reference
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi.reference that throw ValidationException
- java.lang.StringDefaultValidator.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.util.DateDefaultValidator.getValidDate(java.lang.String context, - java.lang.String input, - java.text.DateFormat format, - boolean allowNull) - -
-           
- java.lang.StringDefaultValidator.getValidSafeHTML(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-           
- java.lang.StringDefaultValidator.getValidCreditCard(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated credit card number as a String.
- java.lang.StringDefaultValidator.getValidDirectoryPath(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated directory path as a String.
- java.lang.StringDefaultValidator.getValidFileName(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated file name as a String.
- java.lang.DoubleDefaultValidator.getValidNumber(java.lang.String context, - java.lang.String input, - long minValue, - long maxValue, - boolean allowNull) - -
-          Returns a validated number as a double.
- java.lang.DoubleDefaultValidator.getValidDouble(java.lang.String context, - java.lang.String input, - double minValue, - double maxValue, - boolean allowNull) - -
-          Returns a validated number as a double.
- java.lang.IntegerDefaultValidator.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.
- voidDefaultValidator.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.
- voidDefaultValidator.assertIsValidHTTPRequest() - -
-          Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed - characters.
- voidDefaultValidator.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.StringDefaultValidator.getValidListItem(java.lang.String context, - java.lang.String input, - java.util.List list) - -
-          Returns the list item that exactly matches the canonicalized input.
- voidDefaultValidator.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.StringDefaultValidator.getValidPrintable(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-          Returns canonicalized and validated printable characters as a String.
- java.lang.StringDefaultValidator.getValidRedirectLocation(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated redirect location as a String.
- java.lang.StringDefaultValidator.safeReadLine(java.io.InputStream in, - int max) - -
-          This implementation reads until a newline or the specified number of - characters.
- voidDefaultHTTPUtilities.safeSetHeader(java.lang.String name, - java.lang.String value) - -
-           
- java.util.ListDefaultHTTPUtilities.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.
-  -

- - - - - - - - - - - - - - - - - -
Constructors in org.owasp.esapi.reference that throw ValidationException
DefaultSafeFile(java.lang.String path) - -
-           
DefaultSafeFile(java.lang.String parent, - java.lang.String child) - -
-           
DefaultSafeFile(java.io.File parent, - java.lang.String child) - -
-           
DefaultSafeFile(java.net.URI uri) - -
-           
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/ValidationUploadException.html b/javadoc/org/owasp/esapi/class-use/ValidationUploadException.html deleted file mode 100644 index 4616f540e..000000000 --- a/javadoc/org/owasp/esapi/class-use/ValidationUploadException.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.ValidationUploadException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.ValidationUploadException

-
-No usage of org.owasp.esapi.ValidationUploadException -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/Validator.html b/javadoc/org/owasp/esapi/class-use/Validator.html deleted file mode 100644 index 5bf4a7542..000000000 --- a/javadoc/org/owasp/esapi/class-use/Validator.html +++ /dev/null @@ -1,218 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.Validator - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.Validator

-
- - - - - - - - - - - - - -
-Packages that use Validator
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of Validator in org.owasp.esapi
-  -

- - - - - - - - - -
Methods in org.owasp.esapi that return Validator
-static ValidatorESAPI.validator() - -
-           
-  -

- - - - - - - - - -
Methods in org.owasp.esapi with parameters of type Validator
-static voidESAPI.setValidator(Validator validator) - -
-           
-  -

- - - - - -
-Uses of Validator in org.owasp.esapi.reference
-  -

- - - - - - - - - -
Classes in org.owasp.esapi.reference that implement Validator
- classDefaultValidator - -
-          Reference implementation of the Validator interface.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/class-use/ValidatorTest.html b/javadoc/org/owasp/esapi/class-use/ValidatorTest.html deleted file mode 100644 index 1b62cf389..000000000 --- a/javadoc/org/owasp/esapi/class-use/ValidatorTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.ValidatorTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.ValidatorTest

-
-No usage of org.owasp.esapi.ValidatorTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/codecs/Base64.InputStream.html b/javadoc/org/owasp/esapi/codecs/Base64.InputStream.html deleted file mode 100644 index 81e275550..000000000 --- a/javadoc/org/owasp/esapi/codecs/Base64.InputStream.html +++ /dev/null @@ -1,358 +0,0 @@ - - - - - - -Base64.InputStream - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.codecs -
-Class Base64.InputStream

-
-java.lang.Object
-  extended byjava.io.InputStream
-      extended byjava.io.FilterInputStream
-          extended byorg.owasp.esapi.codecs.Base64.InputStream
-
-
-
Enclosing class:
Base64
-
-
-
-
public static class Base64.InputStream
extends java.io.FilterInputStream
- -

-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. -

- -

-

-
Since:
-
1.3
-
See Also:
Base64
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
Base64.InputStream(java.io.InputStream in) - -
-          Constructs a Base64.InputStream in DECODE mode.
Base64.InputStream(java.io.InputStream in, - int options) - -
-          Constructs a Base64.InputStream in - either ENCODE or DECODE mode.
-  - - - - - - - - - - - - - - - -
-Method Summary
- intread() - -
-          Reads enough of the input stream to convert - to/from Base64 and returns the next byte.
- intread(byte[] dest, - int off, - int len) - -
-          Calls read() repeatedly until the end of stream - is reached or len bytes are read.
- - - - - - - -
Methods inherited from class java.io.FilterInputStream
available, close, mark, markSupported, read, reset, skip
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-Base64.InputStream

-
-public Base64.InputStream(java.io.InputStream in)
-
-
Constructs a Base64.InputStream in DECODE mode. -

-

Parameters:
in - the java.io.InputStream from which to read data.
Since:
-
1.3
-
-
- -

-Base64.InputStream

-
-public Base64.InputStream(java.io.InputStream in,
-                          int options)
-
-
Constructs a Base64.InputStream in - either ENCODE or DECODE mode. -

- Valid options:

-   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.
options - Specified options
Since:
-
2.0
-
See Also:
Base64.ENCODE, -Base64.DECODE, -Base64.DONT_BREAK_LINES
- - - - - - - - -
-Method Detail
- -

-read

-
-public int read()
-         throws java.io.IOException
-
-
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. -
Throws: -
java.io.IOException
Since:
-
1.3
-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/codecs/Base64.OutputStream.html b/javadoc/org/owasp/esapi/codecs/Base64.OutputStream.html deleted file mode 100644 index eb81d9a07..000000000 --- a/javadoc/org/owasp/esapi/codecs/Base64.OutputStream.html +++ /dev/null @@ -1,463 +0,0 @@ - - - - - - -Base64.OutputStream - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.codecs -
-Class Base64.OutputStream

-
-java.lang.Object
-  extended byjava.io.OutputStream
-      extended byjava.io.FilterOutputStream
-          extended byorg.owasp.esapi.codecs.Base64.OutputStream
-
-
-
Enclosing class:
Base64
-
-
-
-
public static class Base64.OutputStream
extends java.io.FilterOutputStream
- -

-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. -

- -

-

-
Since:
-
1.3
-
See Also:
Base64
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
Base64.OutputStream(java.io.OutputStream out) - -
-          Constructs a Base64.OutputStream in ENCODE mode.
Base64.OutputStream(java.io.OutputStream out, - int options) - -
-          Constructs a Base64.OutputStream in - either ENCODE or DECODE mode.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- voidclose() - -
-          Flushes and closes (I think, in the superclass) the stream.
- voidflushBase64() - -
-          Method added by PHIL.
- voidresumeEncoding() - -
-          Resumes encoding of the stream.
- voidsuspendEncoding() - -
-          Suspends encoding of the stream.
- voidwrite(byte[] theBytes, - int off, - int len) - -
-          Calls write(int) repeatedly until len - bytes are written.
- voidwrite(int theByte) - -
-          Writes the byte to the output stream after - converting to/from Base64 notation.
- - - - - - - -
Methods inherited from class java.io.FilterOutputStream
flush, write
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-Base64.OutputStream

-
-public Base64.OutputStream(java.io.OutputStream out)
-
-
Constructs a Base64.OutputStream in ENCODE mode. -

-

Parameters:
out - the java.io.OutputStream to which data will be written.
Since:
-
1.3
-
-
- -

-Base64.OutputStream

-
-public Base64.OutputStream(java.io.OutputStream out,
-                           int options)
-
-
Constructs a Base64.OutputStream in - either ENCODE or DECODE mode. -

- Valid options:

-   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.
options - Specified options.
Since:
-
1.3
-
See Also:
Base64.ENCODE, -Base64.DECODE, -Base64.DONT_BREAK_LINES
- - - - - - - - -
-Method Detail
- -

-write

-
-public void write(int theByte)
-           throws java.io.IOException
-
-
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. -

-

-
Parameters:
theBytes - array from which to read bytes
off - offset for array
len - max number of bytes to read into array -
Throws: -
java.io.IOException
Since:
-
1.3
-
-
-
-
- -

-flushBase64

-
-public void flushBase64()
-                 throws java.io.IOException
-
-
Method added by PHIL. [Thanks, PHIL. -Rob] - This pads the buffer without closing the stream. -

-

- -
Throws: -
java.io.IOException
-
-
-
- -

-close

-
-public void close()
-           throws java.io.IOException
-
-
Flushes and closes (I think, in the superclass) the stream. -

-

- -
Throws: -
java.io.IOException
Since:
-
1.3
-
-
-
-
- -

-suspendEncoding

-
-public void suspendEncoding()
-                     throws java.io.IOException
-
-
Suspends encoding of the stream. - May be helpful if you need to embed a piece of - base640-encoded data in a stream. -

-

- -
Throws: -
java.io.IOException
Since:
-
1.5.1
-
-
-
-
- -

-resumeEncoding

-
-public void resumeEncoding()
-
-
Resumes encoding of the stream. - May be helpful if you need to embed a piece of - base640-encoded data in a stream. -

-

-
Since:
-
1.5.1
-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/codecs/Base64.html b/javadoc/org/owasp/esapi/codecs/Base64.html deleted file mode 100644 index e30611b06..000000000 --- a/javadoc/org/owasp/esapi/codecs/Base64.html +++ /dev/null @@ -1,974 +0,0 @@ - - - - - - -Base64 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.codecs -
-Class Base64

-
-java.lang.Object
-  extended byorg.owasp.esapi.codecs.Base64
-
-
-
-
public class Base64
extends java.lang.Object
- -

-

Encodes and decodes to and from Base64 notation.

-

Homepage: http://iharder.net/base64.

- -

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:

- - String encoded = Base64.encodeBytes( mybytes, Base64.GZIP | Base64.DONT_BREAK_LINES ); - -

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: -
      -
    1. The default is RFC3548 format.
    2. -
    3. 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
    4. -
    5. 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
    6. -
    - 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 classBase64.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 classBase64.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.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Field Summary
-static intDECODE - -
-          Specify decoding.
-static intDONT_BREAK_LINES - -
-          Don't break lines when encoding (violates strict Base64 specification)
-static intENCODE - -
-          Specify encoding.
-static intGZIP - -
-          Specify that data should be gzip-compressed.
-static intNO_OPTIONS - -
-          No options specified.
-static intORDERED - -
-          Encode using the special "ordered" dialect of Base64 described here: - http://www.faqs.org/qa/rfcc-1940.html.
-static intURL_SAFE - -
-          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.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
-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.
-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 booleandecodeFileToFile(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 booleandecodeToFile(java.lang.String dataToDecode, - java.lang.String filename) - -
-          Convenience method for decoding data to a file.
-static java.lang.ObjectdecodeToObject(java.lang.String encodedObject) - -
-          Attempts to decode Base64 data and deserialize a Java - Object within.
-static java.lang.StringencodeBytes(byte[] source) - -
-          Encodes a byte array into Base64 notation.
-static java.lang.StringencodeBytes(byte[] source, - int options) - -
-          Encodes a byte array into Base64 notation.
-static java.lang.StringencodeBytes(byte[] source, - int off, - int len) - -
-          Encodes a byte array into Base64 notation.
-static java.lang.StringencodeBytes(byte[] source, - int off, - int len, - int options) - -
-          Encodes a byte array into Base64 notation.
-static booleanencodeFileToFile(java.lang.String infile, - java.lang.String outfile) - -
-          Reads infile and encodes it to outfile.
-static java.lang.StringencodeFromFile(java.lang.String filename) - -
-          Convenience method for reading a binary file - and base64-encoding it.
-static java.lang.StringencodeObject(java.io.Serializable serializableObject) - -
-          Serializes an object and returns the Base64-encoded - version of that serialized object.
-static java.lang.StringencodeObject(java.io.Serializable serializableObject, - int options) - -
-          Serializes an object and returns the Base64-encoded - version of that serialized object.
-static booleanencodeToFile(byte[] dataToEncode, - java.lang.String filename) - -
-          Convenience method for encoding data to a file.
-static voidmain(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.
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - -
-Field Detail
- -

-NO_OPTIONS

-
-public static final int NO_OPTIONS
-
-
No options specified. Value is zero. -

-

-
See Also:
Constant Field Values
-
-
- -

-ENCODE

-
-public static final int ENCODE
-
-
Specify encoding. -

-

-
See Also:
Constant Field Values
-
-
- -

-DECODE

-
-public static final int DECODE
-
-
Specify decoding. -

-

-
See Also:
Constant Field Values
-
-
- -

-GZIP

-
-public static final int GZIP
-
-
Specify that data should be gzip-compressed. -

-

-
See Also:
Constant Field Values
-
-
- -

-DONT_BREAK_LINES

-
-public static final int DONT_BREAK_LINES
-
-
Don't break lines when encoding (violates strict Base64 specification) -

-

-
See Also:
Constant Field Values
-
-
- -

-URL_SAFE

-
-public static final int URL_SAFE
-
-
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. -

-

-
See Also:
Constant Field Values
-
-
- -

-ORDERED

-
-public static final int ORDERED
-
-
Encode using the special "ordered" dialect of Base64 described here: - http://www.faqs.org/qa/rfcc-1940.html. -

-

-
See Also:
Constant Field Values
-
- - - - - - - - - - - -
-Method Detail
- -

-main

-
-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. -

-

-
-
-
-
- -

-encodeObject

-
-public static java.lang.String encodeObject(java.io.Serializable serializableObject)
-
-
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 -

- Example: encodeObject( myObj, Base64.GZIP | Base64.DONT_BREAK_LINES ) -

-

-
Parameters:
serializableObject - The object to encode
options - Specified options -
Returns:
The Base64-encoded object
Since:
-
2.0
-
See Also:
GZIP, -DONT_BREAK_LINES
-
-
-
- -

-encodeBytes

-
-public static java.lang.String encodeBytes(byte[] source)
-
-
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 -

- Example: encodeBytes( myData, Base64.GZIP | Base64.DONT_BREAK_LINES ) -

-

-
Parameters:
source - The data to convert
options - Specified options
Since:
-
2.0
-
See Also:
GZIP, -DONT_BREAK_LINES
-
-
-
- -

-encodeBytes

-
-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 -

- Example: encodeBytes( myData, Base64.GZIP | Base64.DONT_BREAK_LINES ) -

-

-
Parameters:
source - The data to convert
off - Offset in array where conversion should begin
len - Length of data to convert
options - Specified options
Since:
-
2.0
-
See Also:
GZIP, -DONT_BREAK_LINES
-
-
-
- -

-decode

-
-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. -

-

-
Parameters:
s - the string to decode
options - encode options such as URL_SAFE -
Returns:
the decoded data
Since:
-
1.4
-
-
-
-
- -

-decodeToObject

-
-public static java.lang.Object decodeToObject(java.lang.String encodedObject)
-
-
Attempts to decode Base64 data and deserialize a Java - Object within. Returns null if there was an error. -

-

-
Parameters:
encodedObject - The Base64 data to decode -
Returns:
The decoded and deserialized object
Since:
-
1.5
-
-
-
-
- -

-encodeToFile

-
-public static boolean encodeToFile(byte[] dataToEncode,
-                                   java.lang.String filename)
-
-
Convenience method for encoding data to a file. -

-

-
Parameters:
dataToEncode - byte array of data to encode in base64 form
filename - Filename for saving encoded data -
Returns:
true if successful, false otherwise
Since:
-
2.1
-
-
-
-
- -

-decodeToFile

-
-public static boolean decodeToFile(java.lang.String dataToDecode,
-                                   java.lang.String filename)
-
-
Convenience method for decoding data to a file. -

-

-
Parameters:
dataToDecode - Base64-encoded data as a string
filename - Filename for saving decoded data -
Returns:
true if successful, false otherwise
Since:
-
2.1
-
-
-
-
- -

-decodeFromFile

-
-public static byte[] decodeFromFile(java.lang.String filename)
-
-
Convenience method for reading a base64-encoded - file and decoding it. -

-

-
Parameters:
filename - Filename for reading encoded data -
Returns:
decoded byte array or null if unsuccessful
Since:
-
2.1
-
-
-
-
- -

-encodeFromFile

-
-public static java.lang.String encodeFromFile(java.lang.String filename)
-
-
Convenience method for reading a binary file - and base64-encoding it. -

-

-
Parameters:
filename - Filename for reading binary data -
Returns:
base64-encoded string or null if unsuccessful
Since:
-
2.1
-
-
-
-
- -

-encodeFileToFile

-
-public static boolean encodeFileToFile(java.lang.String infile,
-                                       java.lang.String outfile)
-
-
Reads infile and encodes it to outfile. -

-

-
Parameters:
infile - Input file
outfile - Output file -
Returns:
true if the operation is successful
Since:
-
2.2
-
-
-
-
- -

-decodeFileToFile

-
-public static boolean decodeFileToFile(java.lang.String infile,
-                                       java.lang.String outfile)
-
-
Reads infile and decodes it to outfile. -

-

-
Parameters:
infile - Input file
outfile - Output file -
Returns:
true if the operation is successful
Since:
-
2.2
-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/codecs/CSSCodec.html b/javadoc/org/owasp/esapi/codecs/CSSCodec.html deleted file mode 100644 index 64fc0a666..000000000 --- a/javadoc/org/owasp/esapi/codecs/CSSCodec.html +++ /dev/null @@ -1,346 +0,0 @@ - - - - - - -CSSCodec - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.codecs -
-Class CSSCodec

-
-java.lang.Object
-  extended byorg.owasp.esapi.codecs.CSSCodec
-
-
-
All Implemented Interfaces:
Codec
-
-
-
-
public class CSSCodec
extends java.lang.Object
implements Codec
- -

-Implementation of the Codec interface for backslash encoding frequently used in JavaScript. -

- -

-

-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
-
See Also:
Encoder
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
CSSCodec() - -
-           
-  - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- java.lang.Stringdecode(java.lang.String input) - -
-           
- java.lang.CharacterdecodeCharacter(PushbackString input) - -
-          Returns the decoded version of the character starting at index, or - null if no decoding is possible.
- java.lang.Stringencode(java.lang.String input) - -
-           
- java.lang.StringencodeCharacter(java.lang.Character c) - -
-          Returns backslash encoded character.
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-CSSCodec

-
-public CSSCodec()
-
-
- - - - - - - - -
-Method Detail
- -

-encode

-
-public java.lang.String encode(java.lang.String input)
-
-
-
Specified by:
encode in interface Codec
-
-
-
-
-
-
- -

-encodeCharacter

-
-public java.lang.String encodeCharacter(java.lang.Character c)
-
-
Returns backslash encoded character. This implementation does not support - \\### Latin encoded characters in octal as it is not in ECMAScript v3. -

-

-
Specified by:
encodeCharacter in interface Codec
-
-
-
-
-
-
- -

-decode

-
-public java.lang.String decode(java.lang.String input)
-
-
-
Specified by:
decode in interface Codec
-
-
-
-
-
-
- -

-decodeCharacter

-
-public java.lang.Character decodeCharacter(PushbackString input)
-
-
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 -

-

-
Specified by:
decodeCharacter in interface Codec
-
-
-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/codecs/Codec.html b/javadoc/org/owasp/esapi/codecs/Codec.html deleted file mode 100644 index 48033c85a..000000000 --- a/javadoc/org/owasp/esapi/codecs/Codec.html +++ /dev/null @@ -1,292 +0,0 @@ - - - - - - -Codec - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.codecs -
-Interface Codec

-
-
All Known Implementing Classes:
CSSCodec, HTMLEntityCodec, JavaScriptCodec, MySQLCodec, OracleCodec, PercentCodec, VBScriptCodec
-
-
-
-
public interface 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). 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
-
See Also:
Encoder
-
- -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- java.lang.Stringdecode(java.lang.String input) - -
-           
- java.lang.CharacterdecodeCharacter(PushbackString input) - -
-          Returns the decoded version of the next character from the input string and advances the - current character in the PushbackString.
- java.lang.Stringencode(java.lang.String input) - -
-           
- java.lang.StringencodeCharacter(java.lang.Character c) - -
-           
-  -

- - - - - - - - - - - - - - -
-Method Detail
- -

-encode

-
-public java.lang.String encode(java.lang.String input)
-
-
-
-
-
-
- -

-encodeCharacter

-
-public java.lang.String encodeCharacter(java.lang.Character c)
-
-
-
-
-
-
- -

-decode

-
-public java.lang.String decode(java.lang.String input)
-
-
-
-
-
-
- -

-decodeCharacter

-
-public java.lang.Character decodeCharacter(PushbackString input)
-
-
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. -

-

-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/codecs/HTMLEntityCodec.html b/javadoc/org/owasp/esapi/codecs/HTMLEntityCodec.html deleted file mode 100644 index 36258ae43..000000000 --- a/javadoc/org/owasp/esapi/codecs/HTMLEntityCodec.html +++ /dev/null @@ -1,366 +0,0 @@ - - - - - - -HTMLEntityCodec - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.codecs -
-Class HTMLEntityCodec

-
-java.lang.Object
-  extended byorg.owasp.esapi.codecs.HTMLEntityCodec
-
-
-
All Implemented Interfaces:
Codec
-
-
-
-
public class HTMLEntityCodec
extends java.lang.Object
implements Codec
- -

-Implementation of the Codec interface for HTML entity encoding. -

- -

-

-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
-
See Also:
Encoder
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
HTMLEntityCodec() - -
-           
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- java.lang.Stringdecode(java.lang.String input) - -
-           
- java.lang.CharacterdecodeCharacter(PushbackString input) - -
-          Returns the decoded version of the character starting at index, or - null if no decoding is possible.
- java.lang.Stringencode(java.lang.String input) - -
-           
- java.lang.StringencodeCharacter(java.lang.Character c) - -
-           
-static voidmain(java.lang.String[] args) - -
-           
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-HTMLEntityCodec

-
-public HTMLEntityCodec()
-
-
- - - - - - - - -
-Method Detail
- -

-encode

-
-public java.lang.String encode(java.lang.String input)
-
-
-
Specified by:
encode in interface Codec
-
-
-
-
-
-
- -

-encodeCharacter

-
-public java.lang.String encodeCharacter(java.lang.Character c)
-
-
-
Specified by:
encodeCharacter in interface Codec
-
-
-
-
-
-
- -

-decode

-
-public java.lang.String decode(java.lang.String input)
-
-
-
Specified by:
decode in interface Codec
-
-
-
-
-
-
- -

-decodeCharacter

-
-public java.lang.Character decodeCharacter(PushbackString input)
-
-
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; - &#xhhhh; - &name; -

-

-
Specified by:
decodeCharacter in interface Codec
-
-
-
-
-
-
- -

-main

-
-public static void main(java.lang.String[] args)
-
-
-
-
-
-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/codecs/JavaScriptCodec.html b/javadoc/org/owasp/esapi/codecs/JavaScriptCodec.html deleted file mode 100644 index 441919aa0..000000000 --- a/javadoc/org/owasp/esapi/codecs/JavaScriptCodec.html +++ /dev/null @@ -1,347 +0,0 @@ - - - - - - -JavaScriptCodec - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.codecs -
-Class JavaScriptCodec

-
-java.lang.Object
-  extended byorg.owasp.esapi.codecs.JavaScriptCodec
-
-
-
All Implemented Interfaces:
Codec
-
-
-
-
public class JavaScriptCodec
extends java.lang.Object
implements Codec
- -

-Implementation of the Codec interface for backslash encoding frequently used in JavaScript. -

- -

-

-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
-
See Also:
Encoder
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
JavaScriptCodec() - -
-           
-  - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- java.lang.Stringdecode(java.lang.String input) - -
-           
- java.lang.CharacterdecodeCharacter(PushbackString input) - -
-          Returns the decoded version of the character starting at index, or - null if no decoding is possible.
- java.lang.Stringencode(java.lang.String input) - -
-           
- java.lang.StringencodeCharacter(java.lang.Character c) - -
-          Returns backslash encoded character.
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-JavaScriptCodec

-
-public JavaScriptCodec()
-
-
- - - - - - - - -
-Method Detail
- -

-encode

-
-public java.lang.String encode(java.lang.String input)
-
-
-
Specified by:
encode in interface Codec
-
-
-
-
-
-
- -

-encodeCharacter

-
-public java.lang.String encodeCharacter(java.lang.Character c)
-
-
Returns backslash encoded character. This implementation does not support - \\### Latin encoded characters in octal as it is not in ECMAScript v3. -

-

-
Specified by:
encodeCharacter in interface Codec
-
-
-
-
-
-
- -

-decode

-
-public java.lang.String decode(java.lang.String input)
-
-
-
Specified by:
decode in interface Codec
-
-
-
-
-
-
- -

-decodeCharacter

-
-public java.lang.Character decodeCharacter(PushbackString input)
-
-
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 -

-

-
Specified by:
decodeCharacter in interface Codec
-
-
-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/codecs/MySQLCodec.html b/javadoc/org/owasp/esapi/codecs/MySQLCodec.html deleted file mode 100644 index 743a3f5de..000000000 --- a/javadoc/org/owasp/esapi/codecs/MySQLCodec.html +++ /dev/null @@ -1,395 +0,0 @@ - - - - - - -MySQLCodec - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.codecs -
-Class MySQLCodec

-
-java.lang.Object
-  extended byorg.owasp.esapi.codecs.MySQLCodec
-
-
-
All Implemented Interfaces:
Codec
-
-
-
-
public class MySQLCodec
extends java.lang.Object
implements Codec
- -

-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
-
See Also:
Encoder
-
- -

- - - - - - - - - - - - - - - - - - -
-Field Summary
-static intANSI_MODE - -
-           
-static intMYSQL_MODE - -
-           
-  - - - - - - - - - - -
-Constructor Summary
MySQLCodec(int mode) - -
-           
-  - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- java.lang.Stringdecode(java.lang.String input) - -
-           
- java.lang.CharacterdecodeCharacter(PushbackString input) - -
-          Returns the decoded version of the character starting at index, or - null if no decoding is possible.
- java.lang.Stringencode(java.lang.String input) - -
-           
- java.lang.StringencodeCharacter(java.lang.Character c) - -
-          Returns quote-encoded character
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - -
-Field Detail
- -

-MYSQL_MODE

-
-public static final int MYSQL_MODE
-
-
-
See Also:
Constant Field Values
-
-
- -

-ANSI_MODE

-
-public static final int ANSI_MODE
-
-
-
See Also:
Constant Field Values
-
- - - - - - - - -
-Constructor Detail
- -

-MySQLCodec

-
-public MySQLCodec(int mode)
-
-
- - - - - - - - -
-Method Detail
- -

-encode

-
-public java.lang.String encode(java.lang.String input)
-
-
-
Specified by:
encode in interface Codec
-
-
-
-
-
-
- -

-encodeCharacter

-
-public java.lang.String encodeCharacter(java.lang.Character c)
-
-
Returns quote-encoded character -

-

-
Specified by:
encodeCharacter in interface Codec
-
-
-
-
-
-
- -

-decode

-
-public java.lang.String decode(java.lang.String input)
-
-
-
Specified by:
decode in interface Codec
-
-
-
-
-
-
- -

-decodeCharacter

-
-public java.lang.Character decodeCharacter(PushbackString input)
-
-
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) -

-

-
Specified by:
decodeCharacter in interface Codec
-
-
-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/codecs/OracleCodec.html b/javadoc/org/owasp/esapi/codecs/OracleCodec.html deleted file mode 100644 index b8e9eafcb..000000000 --- a/javadoc/org/owasp/esapi/codecs/OracleCodec.html +++ /dev/null @@ -1,345 +0,0 @@ - - - - - - -OracleCodec - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.codecs -
-Class OracleCodec

-
-java.lang.Object
-  extended byorg.owasp.esapi.codecs.OracleCodec
-
-
-
All Implemented Interfaces:
Codec
-
-
-
-
public class OracleCodec
extends java.lang.Object
implements Codec
- -

-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
-
See Also:
Encoder
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
OracleCodec() - -
-           
-  - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- java.lang.Stringdecode(java.lang.String input) - -
-           
- java.lang.CharacterdecodeCharacter(PushbackString input) - -
-          Returns the decoded version of the character starting at index, or - null if no decoding is possible.
- java.lang.Stringencode(java.lang.String input) - -
-           
- java.lang.StringencodeCharacter(java.lang.Character c) - -
-          Returns quote-encoded character
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-OracleCodec

-
-public OracleCodec()
-
-
- - - - - - - - -
-Method Detail
- -

-encode

-
-public java.lang.String encode(java.lang.String input)
-
-
-
Specified by:
encode in interface Codec
-
-
-
-
-
-
- -

-encodeCharacter

-
-public java.lang.String encodeCharacter(java.lang.Character c)
-
-
Returns quote-encoded character -

-

-
Specified by:
encodeCharacter in interface Codec
-
-
-
-
-
-
- -

-decode

-
-public java.lang.String decode(java.lang.String input)
-
-
-
Specified by:
decode in interface Codec
-
-
-
-
-
-
- -

-decodeCharacter

-
-public java.lang.Character decodeCharacter(PushbackString input)
-
-
Returns the decoded version of the character starting at index, or - null if no decoding is possible. - - Formats all are legal - \c decodes to c -

-

-
Specified by:
decodeCharacter in interface Codec
-
-
-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/codecs/PercentCodec.html b/javadoc/org/owasp/esapi/codecs/PercentCodec.html deleted file mode 100644 index 515df03f0..000000000 --- a/javadoc/org/owasp/esapi/codecs/PercentCodec.html +++ /dev/null @@ -1,342 +0,0 @@ - - - - - - -PercentCodec - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.codecs -
-Class PercentCodec

-
-java.lang.Object
-  extended byorg.owasp.esapi.codecs.PercentCodec
-
-
-
All Implemented Interfaces:
Codec
-
-
-
-
public class PercentCodec
extends java.lang.Object
implements Codec
- -

-Implementation of the Codec interface for percent encoding (aka URL encoding). -

- -

-

-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
-
See Also:
Encoder
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
PercentCodec() - -
-           
-  - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- java.lang.Stringdecode(java.lang.String input) - -
-           
- java.lang.CharacterdecodeCharacter(PushbackString input) - -
-          Returns the decoded version of the character starting at index, or - null if no decoding is possible.
- java.lang.Stringencode(java.lang.String input) - -
-           
- java.lang.StringencodeCharacter(java.lang.Character c) - -
-           
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-PercentCodec

-
-public PercentCodec()
-
-
- - - - - - - - -
-Method Detail
- -

-encode

-
-public java.lang.String encode(java.lang.String input)
-
-
-
Specified by:
encode in interface Codec
-
-
-
-
-
-
- -

-encodeCharacter

-
-public java.lang.String encodeCharacter(java.lang.Character c)
-
-
-
Specified by:
encodeCharacter in interface Codec
-
-
-
-
-
-
- -

-decode

-
-public java.lang.String decode(java.lang.String input)
-
-
-
Specified by:
decode in interface Codec
-
-
-
-
-
-
- -

-decodeCharacter

-
-public java.lang.Character decodeCharacter(PushbackString input)
-
-
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; -

-

-
Specified by:
decodeCharacter in interface Codec
-
-
-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/codecs/PushbackString.html b/javadoc/org/owasp/esapi/codecs/PushbackString.html deleted file mode 100644 index 16e532206..000000000 --- a/javadoc/org/owasp/esapi/codecs/PushbackString.html +++ /dev/null @@ -1,454 +0,0 @@ - - - - - - -PushbackString - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.codecs -
-Class PushbackString

-
-java.lang.Object
-  extended byorg.owasp.esapi.codecs.PushbackString
-
-
-
-
public class PushbackString
extends java.lang.Object
- -

-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
-
See Also:
Encoder
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
PushbackString(java.lang.String input) - -
-           
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- booleanhasNext() - -
-           
- intindex() - -
-           
- booleanisHexDigit(java.lang.Character c) - -
-           
- booleanisPushback() - -
-           
- voidmark() - -
-           
- java.lang.Characternext() - -
-           
- java.lang.CharacternextHex() - -
-           
- java.lang.Characterpeek() - -
-           
- booleanpeek(char c) - -
-           
- voidpushback(java.lang.Character c) - -
-           
- voidreset() - -
-           
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-PushbackString

-
-public PushbackString(java.lang.String input)
-
-
- - - - - - - - -
-Method Detail
- -

-pushback

-
-public void pushback(java.lang.Character c)
-
-
-
-
-
-
- -

-index

-
-public int index()
-
-
-
-
-
-
- -

-hasNext

-
-public boolean hasNext()
-
-
-
-
-
-
- -

-next

-
-public java.lang.Character next()
-
-
-
-
-
-
- -

-nextHex

-
-public java.lang.Character nextHex()
-
-
-
-
-
-
- -

-isHexDigit

-
-public boolean isHexDigit(java.lang.Character c)
-
-
-
-
-
-
- -

-peek

-
-public java.lang.Character peek()
-
-
-
-
-
-
- -

-peek

-
-public boolean peek(char c)
-
-
-
-
-
-
- -

-isPushback

-
-public boolean isPushback()
-
-
-
-
-
-
- -

-mark

-
-public void mark()
-
-
-
-
-
-
- -

-reset

-
-public void reset()
-
-
-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/codecs/VBScriptCodec.html b/javadoc/org/owasp/esapi/codecs/VBScriptCodec.html deleted file mode 100644 index e986a18a1..000000000 --- a/javadoc/org/owasp/esapi/codecs/VBScriptCodec.html +++ /dev/null @@ -1,345 +0,0 @@ - - - - - - -VBScriptCodec - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.codecs -
-Class VBScriptCodec

-
-java.lang.Object
-  extended byorg.owasp.esapi.codecs.VBScriptCodec
-
-
-
All Implemented Interfaces:
Codec
-
-
-
-
public class VBScriptCodec
extends java.lang.Object
implements Codec
- -

-Implementation of the Codec interface for 'quote' encoding from VBScript. -

- -

-

-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
-
See Also:
Encoder
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
VBScriptCodec() - -
-           
-  - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- java.lang.Stringdecode(java.lang.String input) - -
-           
- java.lang.CharacterdecodeCharacter(PushbackString input) - -
-          Returns the decoded version of the character starting at index, or - null if no decoding is possible.
- java.lang.Stringencode(java.lang.String input) - -
-           
- java.lang.StringencodeCharacter(java.lang.Character c) - -
-          Returns quote-encoded character
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-VBScriptCodec

-
-public VBScriptCodec()
-
-
- - - - - - - - -
-Method Detail
- -

-encode

-
-public java.lang.String encode(java.lang.String input)
-
-
-
Specified by:
encode in interface Codec
-
-
-
-
-
-
- -

-encodeCharacter

-
-public java.lang.String encodeCharacter(java.lang.Character c)
-
-
Returns quote-encoded character -

-

-
Specified by:
encodeCharacter in interface Codec
-
-
-
-
-
-
- -

-decode

-
-public java.lang.String decode(java.lang.String input)
-
-
-
Specified by:
decode in interface Codec
-
-
-
-
-
-
- -

-decodeCharacter

-
-public java.lang.Character decodeCharacter(PushbackString input)
-
-
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 -

-

-
Specified by:
decodeCharacter in interface Codec
-
-
-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/codecs/class-use/Base64.InputStream.html b/javadoc/org/owasp/esapi/codecs/class-use/Base64.InputStream.html deleted file mode 100644 index a67afc976..000000000 --- a/javadoc/org/owasp/esapi/codecs/class-use/Base64.InputStream.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.codecs.Base64.InputStream - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.codecs.Base64.InputStream

-
-No usage of org.owasp.esapi.codecs.Base64.InputStream -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/codecs/class-use/Base64.OutputStream.html b/javadoc/org/owasp/esapi/codecs/class-use/Base64.OutputStream.html deleted file mode 100644 index f054a0476..000000000 --- a/javadoc/org/owasp/esapi/codecs/class-use/Base64.OutputStream.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.codecs.Base64.OutputStream - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.codecs.Base64.OutputStream

-
-No usage of org.owasp.esapi.codecs.Base64.OutputStream -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/codecs/class-use/Base64.html b/javadoc/org/owasp/esapi/codecs/class-use/Base64.html deleted file mode 100644 index f6bb41ce8..000000000 --- a/javadoc/org/owasp/esapi/codecs/class-use/Base64.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.codecs.Base64 - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.codecs.Base64

-
-No usage of org.owasp.esapi.codecs.Base64 -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/codecs/class-use/CSSCodec.html b/javadoc/org/owasp/esapi/codecs/class-use/CSSCodec.html deleted file mode 100644 index 6405a0f44..000000000 --- a/javadoc/org/owasp/esapi/codecs/class-use/CSSCodec.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.codecs.CSSCodec - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.codecs.CSSCodec

-
-No usage of org.owasp.esapi.codecs.CSSCodec -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/codecs/class-use/Codec.html b/javadoc/org/owasp/esapi/codecs/class-use/Codec.html deleted file mode 100644 index e452c9d86..000000000 --- a/javadoc/org/owasp/esapi/codecs/class-use/Codec.html +++ /dev/null @@ -1,281 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.codecs.Codec - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.codecs.Codec

-
- - - - - - - - - - - - - - - - - -
-Packages that use Codec
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.codecs  
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of Codec in org.owasp.esapi
-  -

- - - - - - - - - -
Methods in org.owasp.esapi with parameters of type Codec
- java.lang.StringEncoder.encodeForSQL(Codec codec, - java.lang.String input) - -
-          Encode for SQL according to the selected codec.
-  -

- - - - - -
-Uses of Codec in org.owasp.esapi.codecs
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Classes in org.owasp.esapi.codecs that implement Codec
- classCSSCodec - -
-          Implementation of the Codec interface for backslash encoding frequently used in JavaScript.
- classHTMLEntityCodec - -
-          Implementation of the Codec interface for HTML entity encoding.
- classJavaScriptCodec - -
-          Implementation of the Codec interface for backslash encoding frequently used in JavaScript.
- classMySQLCodec - -
-          Implementation of the Codec interface for MySQL strings.
- classOracleCodec - -
-          Implementation of the Codec interface for Oracle strings.
- classPercentCodec - -
-          Implementation of the Codec interface for percent encoding (aka URL encoding).
- classVBScriptCodec - -
-          Implementation of the Codec interface for 'quote' encoding from VBScript.
-  -

- - - - - -
-Uses of Codec in org.owasp.esapi.reference
-  -

- - - - - - - - - -
Methods in org.owasp.esapi.reference with parameters of type Codec
- java.lang.StringDefaultEncoder.encodeForSQL(Codec codec, - java.lang.String input) - -
-          This method is not recommended.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/codecs/class-use/HTMLEntityCodec.html b/javadoc/org/owasp/esapi/codecs/class-use/HTMLEntityCodec.html deleted file mode 100644 index a72c75b91..000000000 --- a/javadoc/org/owasp/esapi/codecs/class-use/HTMLEntityCodec.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.codecs.HTMLEntityCodec - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.codecs.HTMLEntityCodec

-
-No usage of org.owasp.esapi.codecs.HTMLEntityCodec -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/codecs/class-use/JavaScriptCodec.html b/javadoc/org/owasp/esapi/codecs/class-use/JavaScriptCodec.html deleted file mode 100644 index a2d97dd73..000000000 --- a/javadoc/org/owasp/esapi/codecs/class-use/JavaScriptCodec.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.codecs.JavaScriptCodec - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.codecs.JavaScriptCodec

-
-No usage of org.owasp.esapi.codecs.JavaScriptCodec -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/codecs/class-use/MySQLCodec.html b/javadoc/org/owasp/esapi/codecs/class-use/MySQLCodec.html deleted file mode 100644 index 5456786ee..000000000 --- a/javadoc/org/owasp/esapi/codecs/class-use/MySQLCodec.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.codecs.MySQLCodec - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.codecs.MySQLCodec

-
-No usage of org.owasp.esapi.codecs.MySQLCodec -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/codecs/class-use/OracleCodec.html b/javadoc/org/owasp/esapi/codecs/class-use/OracleCodec.html deleted file mode 100644 index bce515042..000000000 --- a/javadoc/org/owasp/esapi/codecs/class-use/OracleCodec.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.codecs.OracleCodec - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.codecs.OracleCodec

-
-No usage of org.owasp.esapi.codecs.OracleCodec -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/codecs/class-use/PercentCodec.html b/javadoc/org/owasp/esapi/codecs/class-use/PercentCodec.html deleted file mode 100644 index 3ed4aa7d6..000000000 --- a/javadoc/org/owasp/esapi/codecs/class-use/PercentCodec.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.codecs.PercentCodec - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.codecs.PercentCodec

-
-No usage of org.owasp.esapi.codecs.PercentCodec -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/codecs/class-use/PushbackString.html b/javadoc/org/owasp/esapi/codecs/class-use/PushbackString.html deleted file mode 100644 index f354a9ac2..000000000 --- a/javadoc/org/owasp/esapi/codecs/class-use/PushbackString.html +++ /dev/null @@ -1,236 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.codecs.PushbackString - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.codecs.PushbackString

-
- - - - - - - - - -
-Packages that use PushbackString
org.owasp.esapi.codecs  
-  -

- - - - - -
-Uses of PushbackString in org.owasp.esapi.codecs
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi.codecs with parameters of type PushbackString
- java.lang.CharacterVBScriptCodec.decodeCharacter(PushbackString input) - -
-          Returns the decoded version of the character starting at index, or - null if no decoding is possible.
- java.lang.CharacterPercentCodec.decodeCharacter(PushbackString input) - -
-          Returns the decoded version of the character starting at index, or - null if no decoding is possible.
- java.lang.CharacterOracleCodec.decodeCharacter(PushbackString input) - -
-          Returns the decoded version of the character starting at index, or - null if no decoding is possible.
- java.lang.CharacterMySQLCodec.decodeCharacter(PushbackString input) - -
-          Returns the decoded version of the character starting at index, or - null if no decoding is possible.
- java.lang.CharacterJavaScriptCodec.decodeCharacter(PushbackString input) - -
-          Returns the decoded version of the character starting at index, or - null if no decoding is possible.
- java.lang.CharacterHTMLEntityCodec.decodeCharacter(PushbackString input) - -
-          Returns the decoded version of the character starting at index, or - null if no decoding is possible.
- java.lang.CharacterCSSCodec.decodeCharacter(PushbackString input) - -
-          Returns the decoded version of the character starting at index, or - null if no decoding is possible.
- java.lang.CharacterCodec.decodeCharacter(PushbackString input) - -
-          Returns the decoded version of the next character from the input string and advances the - current character in the PushbackString.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/codecs/class-use/VBScriptCodec.html b/javadoc/org/owasp/esapi/codecs/class-use/VBScriptCodec.html deleted file mode 100644 index 4357a494d..000000000 --- a/javadoc/org/owasp/esapi/codecs/class-use/VBScriptCodec.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.codecs.VBScriptCodec - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.codecs.VBScriptCodec

-
-No usage of org.owasp.esapi.codecs.VBScriptCodec -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/codecs/package-frame.html b/javadoc/org/owasp/esapi/codecs/package-frame.html deleted file mode 100644 index dd930822f..000000000 --- a/javadoc/org/owasp/esapi/codecs/package-frame.html +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - -org.owasp.esapi.codecs - - - - - - - - - - - -org.owasp.esapi.codecs - - - - -
-Interfaces  - -
-Codec
- - - - - - -
-Classes  - -
-Base64 -
-Base64.InputStream -
-Base64.OutputStream -
-CSSCodec -
-HTMLEntityCodec -
-JavaScriptCodec -
-MySQLCodec -
-OracleCodec -
-PercentCodec -
-PushbackString -
-VBScriptCodec
- - - - diff --git a/javadoc/org/owasp/esapi/codecs/package-summary.html b/javadoc/org/owasp/esapi/codecs/package-summary.html deleted file mode 100644 index 571fd3c75..000000000 --- a/javadoc/org/owasp/esapi/codecs/package-summary.html +++ /dev/null @@ -1,208 +0,0 @@ - - - - - - -org.owasp.esapi.codecs - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-

-Package org.owasp.esapi.codecs -

- - - - - - - - - -
-Interface Summary
CodecThe 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).
-  - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Class Summary
Base64Encodes and decodes to and from Base64 notation.
Base64.InputStreamA Base64.InputStream will read data from another - java.io.InputStream, given in the constructor, - and encode/decode to/from Base64 notation on the fly.
Base64.OutputStreamA Base64.OutputStream will write data to another - java.io.OutputStream, given in the constructor, - and encode/decode to/from Base64 notation on the fly.
CSSCodecImplementation of the Codec interface for backslash encoding frequently used in JavaScript.
HTMLEntityCodecImplementation of the Codec interface for HTML entity encoding.
JavaScriptCodecImplementation of the Codec interface for backslash encoding frequently used in JavaScript.
MySQLCodecImplementation of the Codec interface for MySQL strings.
OracleCodecImplementation of the Codec interface for Oracle strings.
PercentCodecImplementation of the Codec interface for percent encoding (aka URL encoding).
PushbackStringThe pushback string is used by Codecs to allow them to push decoded characters back onto a string - for further decoding.
VBScriptCodecImplementation of the Codec interface for 'quote' encoding from VBScript.
-  - -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/codecs/package-tree.html b/javadoc/org/owasp/esapi/codecs/package-tree.html deleted file mode 100644 index f14f487dd..000000000 --- a/javadoc/org/owasp/esapi/codecs/package-tree.html +++ /dev/null @@ -1,165 +0,0 @@ - - - - - - -org.owasp.esapi.codecs Class Hierarchy - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Hierarchy For Package org.owasp.esapi.codecs -

-
-
-
Package Hierarchies:
All Packages
-
-

-Class Hierarchy -

-
    -
  • class java.lang.Object
      -
    • class org.owasp.esapi.codecs.Base64
    • class org.owasp.esapi.codecs.CSSCodec (implements org.owasp.esapi.codecs.Codec) -
    • class org.owasp.esapi.codecs.HTMLEntityCodec (implements org.owasp.esapi.codecs.Codec) -
    • class java.io.InputStream -
    • class org.owasp.esapi.codecs.JavaScriptCodec (implements org.owasp.esapi.codecs.Codec) -
    • class org.owasp.esapi.codecs.MySQLCodec (implements org.owasp.esapi.codecs.Codec) -
    • class org.owasp.esapi.codecs.OracleCodec (implements org.owasp.esapi.codecs.Codec) -
    • class java.io.OutputStream -
    • class org.owasp.esapi.codecs.PercentCodec (implements org.owasp.esapi.codecs.Codec) -
    • class org.owasp.esapi.codecs.PushbackString
    • class org.owasp.esapi.codecs.VBScriptCodec (implements org.owasp.esapi.codecs.Codec) -
    -
-

-Interface Hierarchy -

-
    -
  • interface org.owasp.esapi.codecs.Codec
-
- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/codecs/package-use.html b/javadoc/org/owasp/esapi/codecs/package-use.html deleted file mode 100644 index 4a3f9f567..000000000 --- a/javadoc/org/owasp/esapi/codecs/package-use.html +++ /dev/null @@ -1,211 +0,0 @@ - - - - - - -Uses of Package org.owasp.esapi.codecs - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Package
org.owasp.esapi.codecs

-
- - - - - - - - - - - - - - - - - -
-Packages that use org.owasp.esapi.codecs
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.codecs  
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - - - - -
-Classes in org.owasp.esapi.codecs used by org.owasp.esapi
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).
-  -

- - - - - - - - - - - -
-Classes in org.owasp.esapi.codecs used by org.owasp.esapi.codecs
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.
-  -

- - - - - - - - -
-Classes in org.owasp.esapi.codecs used by org.owasp.esapi.reference
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).
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/AccessControlException.html b/javadoc/org/owasp/esapi/errors/AccessControlException.html deleted file mode 100644 index 82c67d47d..000000000 --- a/javadoc/org/owasp/esapi/errors/AccessControlException.html +++ /dev/null @@ -1,277 +0,0 @@ - - - - - - -AccessControlException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.errors -
-Class AccessControlException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.errors.EnterpriseSecurityException
-              extended byorg.owasp.esapi.errors.AccessControlException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
-
public class AccessControlException
extends EnterpriseSecurityException
- -

-An AccessControlException should be thrown when a user attempts to access a - resource that they are not authorized for. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
AccessControlException(java.lang.String userMessage, - java.lang.String logMessage) - -
-          Creates a new instance of EnterpriseSecurityException.
AccessControlException(java.lang.String userMessage, - java.lang.String logMessage, - java.lang.Throwable cause) - -
-          Instantiates a new access control exception.
-  - - - - - - - - - - -
Methods inherited from class org.owasp.esapi.errors.EnterpriseSecurityException
getLogMessage, getUserMessage
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-AccessControlException

-
-public AccessControlException(java.lang.String userMessage,
-                              java.lang.String logMessage)
-
-
Creates a new instance of EnterpriseSecurityException. -

-

-
- -

-AccessControlException

-
-public AccessControlException(java.lang.String userMessage,
-                              java.lang.String logMessage,
-                              java.lang.Throwable cause)
-
-
Instantiates a new access control exception. -

-

Parameters:
cause - the cause
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/AuthenticationAccountsException.html b/javadoc/org/owasp/esapi/errors/AuthenticationAccountsException.html deleted file mode 100644 index faedaa7c0..000000000 --- a/javadoc/org/owasp/esapi/errors/AuthenticationAccountsException.html +++ /dev/null @@ -1,279 +0,0 @@ - - - - - - -AuthenticationAccountsException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.errors -
-Class AuthenticationAccountsException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.errors.EnterpriseSecurityException
-              extended byorg.owasp.esapi.errors.AuthenticationException
-                  extended byorg.owasp.esapi.errors.AuthenticationAccountsException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
-
public class AuthenticationAccountsException
extends AuthenticationException
- -

-An AuthenticationException should be thrown when anything goes wrong during - login or logout. They are also appropriate for any problems related to - identity management. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
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.
-  - - - - - - - - - - -
Methods inherited from class org.owasp.esapi.errors.EnterpriseSecurityException
getLogMessage, getUserMessage
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-AuthenticationAccountsException

-
-public AuthenticationAccountsException(java.lang.String userMessage,
-                                       java.lang.String logMessage)
-
-
Creates a new instance of EnterpriseSecurityException. -

-

-
- -

-AuthenticationAccountsException

-
-public AuthenticationAccountsException(java.lang.String userMessage,
-                                       java.lang.String logMessage,
-                                       java.lang.Throwable cause)
-
-
Instantiates a new authentication exception. -

-

Parameters:
cause - the cause
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/AuthenticationCredentialsException.html b/javadoc/org/owasp/esapi/errors/AuthenticationCredentialsException.html deleted file mode 100644 index 5982827f4..000000000 --- a/javadoc/org/owasp/esapi/errors/AuthenticationCredentialsException.html +++ /dev/null @@ -1,279 +0,0 @@ - - - - - - -AuthenticationCredentialsException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.errors -
-Class AuthenticationCredentialsException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.errors.EnterpriseSecurityException
-              extended byorg.owasp.esapi.errors.AuthenticationException
-                  extended byorg.owasp.esapi.errors.AuthenticationCredentialsException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
-
public class AuthenticationCredentialsException
extends AuthenticationException
- -

-An AuthenticationException should be thrown when anything goes wrong during - login or logout. They are also appropriate for any problems related to - identity management. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
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.
-  - - - - - - - - - - -
Methods inherited from class org.owasp.esapi.errors.EnterpriseSecurityException
getLogMessage, getUserMessage
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-AuthenticationCredentialsException

-
-public AuthenticationCredentialsException(java.lang.String userMessage,
-                                          java.lang.String logMessage)
-
-
Creates a new instance of EnterpriseSecurityException. -

-

-
- -

-AuthenticationCredentialsException

-
-public AuthenticationCredentialsException(java.lang.String userMessage,
-                                          java.lang.String logMessage,
-                                          java.lang.Throwable cause)
-
-
Instantiates a new authentication exception. -

-

Parameters:
cause - the cause
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/AuthenticationException.html b/javadoc/org/owasp/esapi/errors/AuthenticationException.html deleted file mode 100644 index b8501867b..000000000 --- a/javadoc/org/owasp/esapi/errors/AuthenticationException.html +++ /dev/null @@ -1,281 +0,0 @@ - - - - - - -AuthenticationException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.errors -
-Class AuthenticationException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.errors.EnterpriseSecurityException
-              extended byorg.owasp.esapi.errors.AuthenticationException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
Direct Known Subclasses:
AuthenticationAccountsException, AuthenticationCredentialsException, AuthenticationHostException, AuthenticationLoginException
-
-
-
-
public class AuthenticationException
extends EnterpriseSecurityException
- -

-An AuthenticationException should be thrown when anything goes wrong during - login or logout. They are also appropriate for any problems related to - identity management. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
AuthenticationException(java.lang.String userMessage, - java.lang.String logMessage) - -
-          Creates a new instance of EnterpriseSecurityException.
AuthenticationException(java.lang.String userMessage, - java.lang.String logMessage, - java.lang.Throwable cause) - -
-          Instantiates a new authentication exception.
-  - - - - - - - - - - -
Methods inherited from class org.owasp.esapi.errors.EnterpriseSecurityException
getLogMessage, getUserMessage
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-AuthenticationException

-
-public AuthenticationException(java.lang.String userMessage,
-                               java.lang.String logMessage)
-
-
Creates a new instance of EnterpriseSecurityException. -

-

-
- -

-AuthenticationException

-
-public AuthenticationException(java.lang.String userMessage,
-                               java.lang.String logMessage,
-                               java.lang.Throwable cause)
-
-
Instantiates a new authentication exception. -

-

Parameters:
cause - the cause
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/AuthenticationHostException.html b/javadoc/org/owasp/esapi/errors/AuthenticationHostException.html deleted file mode 100644 index 9d7b6a720..000000000 --- a/javadoc/org/owasp/esapi/errors/AuthenticationHostException.html +++ /dev/null @@ -1,278 +0,0 @@ - - - - - - -AuthenticationHostException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.errors -
-Class AuthenticationHostException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.errors.EnterpriseSecurityException
-              extended byorg.owasp.esapi.errors.AuthenticationException
-                  extended byorg.owasp.esapi.errors.AuthenticationHostException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
-
public class AuthenticationHostException
extends AuthenticationException
- -

-An AuthenticationHostException should be thrown when there is a problem with - the host involved with authentication, particularly if the host changes unexpectedly. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
AuthenticationHostException(java.lang.String userMessage, - java.lang.String logMessage) - -
-          Creates a new instance of AuthenticationHostException.
AuthenticationHostException(java.lang.String userMessage, - java.lang.String logMessage, - java.lang.Throwable cause) - -
-          Instantiates a new authentication exception.
-  - - - - - - - - - - -
Methods inherited from class org.owasp.esapi.errors.EnterpriseSecurityException
getLogMessage, getUserMessage
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-AuthenticationHostException

-
-public AuthenticationHostException(java.lang.String userMessage,
-                                   java.lang.String logMessage)
-
-
Creates a new instance of AuthenticationHostException. -

-

-
- -

-AuthenticationHostException

-
-public AuthenticationHostException(java.lang.String userMessage,
-                                   java.lang.String logMessage,
-                                   java.lang.Throwable cause)
-
-
Instantiates a new authentication exception. -

-

Parameters:
cause - the cause
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/AuthenticationLoginException.html b/javadoc/org/owasp/esapi/errors/AuthenticationLoginException.html deleted file mode 100644 index e163301a9..000000000 --- a/javadoc/org/owasp/esapi/errors/AuthenticationLoginException.html +++ /dev/null @@ -1,279 +0,0 @@ - - - - - - -AuthenticationLoginException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.errors -
-Class AuthenticationLoginException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.errors.EnterpriseSecurityException
-              extended byorg.owasp.esapi.errors.AuthenticationException
-                  extended byorg.owasp.esapi.errors.AuthenticationLoginException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
-
public class AuthenticationLoginException
extends AuthenticationException
- -

-An AuthenticationException should be thrown when anything goes wrong during - login or logout. They are also appropriate for any problems related to - identity management. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
AuthenticationLoginException(java.lang.String userMessage, - java.lang.String logMessage) - -
-          Creates a new instance of EnterpriseSecurityException.
AuthenticationLoginException(java.lang.String userMessage, - java.lang.String logMessage, - java.lang.Throwable cause) - -
-          Instantiates a new authentication exception.
-  - - - - - - - - - - -
Methods inherited from class org.owasp.esapi.errors.EnterpriseSecurityException
getLogMessage, getUserMessage
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-AuthenticationLoginException

-
-public AuthenticationLoginException(java.lang.String userMessage,
-                                    java.lang.String logMessage)
-
-
Creates a new instance of EnterpriseSecurityException. -

-

-
- -

-AuthenticationLoginException

-
-public AuthenticationLoginException(java.lang.String userMessage,
-                                    java.lang.String logMessage,
-                                    java.lang.Throwable cause)
-
-
Instantiates a new authentication exception. -

-

Parameters:
cause - the cause
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/AvailabilityException.html b/javadoc/org/owasp/esapi/errors/AvailabilityException.html deleted file mode 100644 index 460d0c5f9..000000000 --- a/javadoc/org/owasp/esapi/errors/AvailabilityException.html +++ /dev/null @@ -1,278 +0,0 @@ - - - - - - -AvailabilityException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.errors -
-Class AvailabilityException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.errors.EnterpriseSecurityException
-              extended byorg.owasp.esapi.errors.AvailabilityException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
-
public class AvailabilityException
extends EnterpriseSecurityException
- -

-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. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
AvailabilityException(java.lang.String userMessage, - java.lang.String logMessage) - -
-          Creates a new instance of AvailabilityException.
AvailabilityException(java.lang.String userMessage, - java.lang.String logMessage, - java.lang.Throwable cause) - -
-          Instantiates a new AvailabilityException.
-  - - - - - - - - - - -
Methods inherited from class org.owasp.esapi.errors.EnterpriseSecurityException
getLogMessage, getUserMessage
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-AvailabilityException

-
-public AvailabilityException(java.lang.String userMessage,
-                             java.lang.String logMessage)
-
-
Creates a new instance of AvailabilityException. -

-

-
- -

-AvailabilityException

-
-public AvailabilityException(java.lang.String userMessage,
-                             java.lang.String logMessage,
-                             java.lang.Throwable cause)
-
-
Instantiates a new AvailabilityException. -

-

Parameters:
cause - the cause
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/CertificateException.html b/javadoc/org/owasp/esapi/errors/CertificateException.html deleted file mode 100644 index 34047cd48..000000000 --- a/javadoc/org/owasp/esapi/errors/CertificateException.html +++ /dev/null @@ -1,277 +0,0 @@ - - - - - - -CertificateException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.errors -
-Class CertificateException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.errors.EnterpriseSecurityException
-              extended byorg.owasp.esapi.errors.CertificateException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
-
public class CertificateException
extends EnterpriseSecurityException
- -

-A CertificateException should be thrown for any problems that arise during - processing of digital certificates. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
CertificateException(java.lang.String userMessage, - java.lang.String logMessage) - -
-          Creates a new instance of CertificateException.
CertificateException(java.lang.String userMessage, - java.lang.String logMessage, - java.lang.Throwable cause) - -
-          Instantiates a new CertificateException.
-  - - - - - - - - - - -
Methods inherited from class org.owasp.esapi.errors.EnterpriseSecurityException
getLogMessage, getUserMessage
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-CertificateException

-
-public CertificateException(java.lang.String userMessage,
-                            java.lang.String logMessage)
-
-
Creates a new instance of CertificateException. -

-

-
- -

-CertificateException

-
-public CertificateException(java.lang.String userMessage,
-                            java.lang.String logMessage,
-                            java.lang.Throwable cause)
-
-
Instantiates a new CertificateException. -

-

Parameters:
cause - the cause
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/EncodingException.html b/javadoc/org/owasp/esapi/errors/EncodingException.html deleted file mode 100644 index 8c084587a..000000000 --- a/javadoc/org/owasp/esapi/errors/EncodingException.html +++ /dev/null @@ -1,277 +0,0 @@ - - - - - - -EncodingException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.errors -
-Class EncodingException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.errors.EnterpriseSecurityException
-              extended byorg.owasp.esapi.errors.EncodingException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
-
public class EncodingException
extends EnterpriseSecurityException
- -

-An ExecutorException should be thrown for any problems that occur when - encoding or decoding data. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
EncodingException(java.lang.String userMessage, - java.lang.String logMessage) - -
-          Creates a new instance of EncodingException.
EncodingException(java.lang.String userMessage, - java.lang.String logMessage, - java.lang.Throwable cause) - -
-          Instantiates a new EncodingException.
-  - - - - - - - - - - -
Methods inherited from class org.owasp.esapi.errors.EnterpriseSecurityException
getLogMessage, getUserMessage
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-EncodingException

-
-public EncodingException(java.lang.String userMessage,
-                         java.lang.String logMessage)
-
-
Creates a new instance of EncodingException. -

-

-
- -

-EncodingException

-
-public EncodingException(java.lang.String userMessage,
-                         java.lang.String logMessage,
-                         java.lang.Throwable cause)
-
-
Instantiates a new EncodingException. -

-

Parameters:
cause - the cause
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/EncryptionException.html b/javadoc/org/owasp/esapi/errors/EncryptionException.html deleted file mode 100644 index 9c64ef350..000000000 --- a/javadoc/org/owasp/esapi/errors/EncryptionException.html +++ /dev/null @@ -1,277 +0,0 @@ - - - - - - -EncryptionException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.errors -
-Class EncryptionException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.errors.EnterpriseSecurityException
-              extended byorg.owasp.esapi.errors.EncryptionException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
-
public class EncryptionException
extends EnterpriseSecurityException
- -

-An EncryptionException should be thrown for any problems related to - encryption, hashing, or digital signatures. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
EncryptionException(java.lang.String userMessage, - java.lang.String logMessage) - -
-          Creates a new instance of EncryptionException.
EncryptionException(java.lang.String userMessage, - java.lang.String logMessage, - java.lang.Throwable cause) - -
-          Instantiates a new EncryptionException.
-  - - - - - - - - - - -
Methods inherited from class org.owasp.esapi.errors.EnterpriseSecurityException
getLogMessage, getUserMessage
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-EncryptionException

-
-public EncryptionException(java.lang.String userMessage,
-                           java.lang.String logMessage)
-
-
Creates a new instance of EncryptionException. -

-

-
- -

-EncryptionException

-
-public EncryptionException(java.lang.String userMessage,
-                           java.lang.String logMessage,
-                           java.lang.Throwable cause)
-
-
Instantiates a new EncryptionException. -

-

Parameters:
cause - the cause
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/EnterpriseSecurityException.html b/javadoc/org/owasp/esapi/errors/EnterpriseSecurityException.html deleted file mode 100644 index 7d0d088ea..000000000 --- a/javadoc/org/owasp/esapi/errors/EnterpriseSecurityException.html +++ /dev/null @@ -1,334 +0,0 @@ - - - - - - -EnterpriseSecurityException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.errors -
-Class EnterpriseSecurityException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.errors.EnterpriseSecurityException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
Direct Known Subclasses:
AccessControlException, AuthenticationException, AvailabilityException, CertificateException, EncodingException, EncryptionException, ExecutorException, IntegrityException, ValidationException
-
-
-
-
public class EnterpriseSecurityException
extends java.lang.Exception
- -

-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. -

-

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
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.
-  - - - - - - - - - - - - - - - -
-Method Summary
- java.lang.StringgetLogMessage() - -
-           
- java.lang.StringgetUserMessage() - -
-           
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-EnterpriseSecurityException

-
-public EnterpriseSecurityException(java.lang.String userMessage,
-                                   java.lang.String logMessage)
-
-
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. -

-

-
- -

-EnterpriseSecurityException

-
-public 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. -

-

Parameters:
cause - the cause
- - - - - - - - -
-Method Detail
- -

-getUserMessage

-
-public java.lang.String getUserMessage()
-
-
-
-
-
-
- -

-getLogMessage

-
-public java.lang.String getLogMessage()
-
-
-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/EnterpriseSecurityExceptionTest.html b/javadoc/org/owasp/esapi/errors/EnterpriseSecurityExceptionTest.html deleted file mode 100644 index 2fcfbb8b0..000000000 --- a/javadoc/org/owasp/esapi/errors/EnterpriseSecurityExceptionTest.html +++ /dev/null @@ -1,311 +0,0 @@ - - - - - - -EnterpriseSecurityExceptionTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.errors -
-Class EnterpriseSecurityExceptionTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.errors.EnterpriseSecurityExceptionTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class EnterpriseSecurityExceptionTest
extends junit.framework.TestCase
- -

-The Class AccessReferenceMapTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
EnterpriseSecurityExceptionTest(java.lang.String testName) - -
-          Instantiates a new access reference map test.
-  - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestExceptions() - -
-          Test of update method, of class org.owasp.esapi.AccessReferenceMap.
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-EnterpriseSecurityExceptionTest

-
-public EnterpriseSecurityExceptionTest(java.lang.String testName)
-
-
Instantiates a new access reference map test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testExceptions

-
-public void testExceptions()
-
-
Test of update method, of class org.owasp.esapi.AccessReferenceMap. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/ExecutorException.html b/javadoc/org/owasp/esapi/errors/ExecutorException.html deleted file mode 100644 index 4e8f1fcfa..000000000 --- a/javadoc/org/owasp/esapi/errors/ExecutorException.html +++ /dev/null @@ -1,277 +0,0 @@ - - - - - - -ExecutorException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.errors -
-Class ExecutorException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.errors.EnterpriseSecurityException
-              extended byorg.owasp.esapi.errors.ExecutorException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
-
public class ExecutorException
extends EnterpriseSecurityException
- -

-An ExecutorException should be thrown for any problems that arise during the - execution of a system executable. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
ExecutorException(java.lang.String userMessage, - java.lang.String logMessage) - -
-          Creates a new instance of ExecutorException.
ExecutorException(java.lang.String userMessage, - java.lang.String logMessage, - java.lang.Throwable cause) - -
-          Instantiates a new ExecutorException.
-  - - - - - - - - - - -
Methods inherited from class org.owasp.esapi.errors.EnterpriseSecurityException
getLogMessage, getUserMessage
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-ExecutorException

-
-public ExecutorException(java.lang.String userMessage,
-                         java.lang.String logMessage)
-
-
Creates a new instance of ExecutorException. -

-

-
- -

-ExecutorException

-
-public ExecutorException(java.lang.String userMessage,
-                         java.lang.String logMessage,
-                         java.lang.Throwable cause)
-
-
Instantiates a new ExecutorException. -

-

Parameters:
cause - the cause
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/IntegrityException.html b/javadoc/org/owasp/esapi/errors/IntegrityException.html deleted file mode 100644 index dd2ef5ef3..000000000 --- a/javadoc/org/owasp/esapi/errors/IntegrityException.html +++ /dev/null @@ -1,278 +0,0 @@ - - - - - - -IntegrityException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.errors -
-Class IntegrityException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.errors.EnterpriseSecurityException
-              extended byorg.owasp.esapi.errors.IntegrityException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
-
public class IntegrityException
extends EnterpriseSecurityException
- -

-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. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
IntegrityException(java.lang.String userMessage, - java.lang.String logMessage) - -
-          Creates a new instance of IntegrityException.
IntegrityException(java.lang.String userMessage, - java.lang.String logMessage, - java.lang.Throwable cause) - -
-          Instantiates a new IntegrityException.
-  - - - - - - - - - - -
Methods inherited from class org.owasp.esapi.errors.EnterpriseSecurityException
getLogMessage, getUserMessage
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-IntegrityException

-
-public IntegrityException(java.lang.String userMessage,
-                          java.lang.String logMessage)
-
-
Creates a new instance of IntegrityException. -

-

-
- -

-IntegrityException

-
-public IntegrityException(java.lang.String userMessage,
-                          java.lang.String logMessage,
-                          java.lang.Throwable cause)
-
-
Instantiates a new IntegrityException. -

-

Parameters:
cause - the cause
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/IntrusionException.html b/javadoc/org/owasp/esapi/errors/IntrusionException.html deleted file mode 100644 index 97eea8b8e..000000000 --- a/javadoc/org/owasp/esapi/errors/IntrusionException.html +++ /dev/null @@ -1,323 +0,0 @@ - - - - - - -IntrusionException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.errors -
-Class IntrusionException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byjava.lang.RuntimeException
-              extended byorg.owasp.esapi.errors.IntrusionException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
-
public class IntrusionException
extends java.lang.RuntimeException
- -

-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. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
IntrusionException(java.lang.String userMessage, - java.lang.String logMessage) - -
-          Creates a new instance of IntrusionException.
IntrusionException(java.lang.String userMessage, - java.lang.String logMessage, - java.lang.Throwable cause) - -
-          Instantiates a new intrusion exception.
-  - - - - - - - - - - - - - - - -
-Method Summary
- java.lang.StringgetLogMessage() - -
-           
- java.lang.StringgetUserMessage() - -
-           
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-IntrusionException

-
-public IntrusionException(java.lang.String userMessage,
-                          java.lang.String logMessage)
-
-
Creates a new instance of IntrusionException. -

-

-
- -

-IntrusionException

-
-public IntrusionException(java.lang.String userMessage,
-                          java.lang.String logMessage,
-                          java.lang.Throwable cause)
-
-
Instantiates a new intrusion exception. -

-

Parameters:
cause - the cause
- - - - - - - - -
-Method Detail
- -

-getUserMessage

-
-public java.lang.String getUserMessage()
-
-
-
-
-
-
- -

-getLogMessage

-
-public java.lang.String getLogMessage()
-
-
-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/ValidationAvailabilityException.html b/javadoc/org/owasp/esapi/errors/ValidationAvailabilityException.html deleted file mode 100644 index 2aca62cb6..000000000 --- a/javadoc/org/owasp/esapi/errors/ValidationAvailabilityException.html +++ /dev/null @@ -1,282 +0,0 @@ - - - - - - -ValidationAvailabilityException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.errors -
-Class ValidationAvailabilityException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.errors.EnterpriseSecurityException
-              extended byorg.owasp.esapi.errors.ValidationException
-                  extended byorg.owasp.esapi.errors.ValidationAvailabilityException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
-
public class ValidationAvailabilityException
extends ValidationException
- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
ValidationAvailabilityException(java.lang.String userMessage, - java.lang.String logMessage) - -
-          Create a new ValidationException
ValidationAvailabilityException(java.lang.String userMessage, - java.lang.String logMessage, - java.lang.Throwable cause) - -
-          Create a new ValidationException
-  - - - - - - - - - - -
Methods inherited from class org.owasp.esapi.errors.ValidationException
getContext, getSerialVersionUID, setContext
- - - - - - - -
Methods inherited from class org.owasp.esapi.errors.EnterpriseSecurityException
getLogMessage, getUserMessage
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-ValidationAvailabilityException

-
-public ValidationAvailabilityException(java.lang.String userMessage,
-                                       java.lang.String logMessage)
-
-
Create a new ValidationException -

-

Parameters:
userMessage -
logMessage -
-
- -

-ValidationAvailabilityException

-
-public ValidationAvailabilityException(java.lang.String userMessage,
-                                       java.lang.String logMessage,
-                                       java.lang.Throwable cause)
-
-
Create a new ValidationException -

-

Parameters:
userMessage -
logMessage -
cause -
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/ValidationException.html b/javadoc/org/owasp/esapi/errors/ValidationException.html deleted file mode 100644 index 2287f1ab5..000000000 --- a/javadoc/org/owasp/esapi/errors/ValidationException.html +++ /dev/null @@ -1,398 +0,0 @@ - - - - - - -ValidationException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.errors -
-Class ValidationException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.errors.EnterpriseSecurityException
-              extended byorg.owasp.esapi.errors.ValidationException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
Direct Known Subclasses:
ValidationAvailabilityException, ValidationUploadException
-
-
-
-
public class ValidationException
extends EnterpriseSecurityException
- -

-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. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - - - - - - - -
-Constructor Summary
ValidationException(java.lang.String userMessage, - java.lang.String logMessage) - -
-          Creates a new instance of ValidationException.
ValidationException(java.lang.String userMessage, - java.lang.String logMessage, - java.lang.String context) - -
-          Creates a new instance of ValidationException.
ValidationException(java.lang.String userMessage, - java.lang.String logMessage, - java.lang.Throwable cause) - -
-          Instantiates a new ValidationException.
ValidationException(java.lang.String userMessage, - java.lang.String logMessage, - java.lang.Throwable cause, - java.lang.String context) - -
-          Instantiates a new ValidationException.
-  - - - - - - - - - - - - - - - - - - - -
-Method Summary
- java.lang.StringgetContext() - -
-          Returns the UI reference that caused this ValidationException
-static longgetSerialVersionUID() - -
-           
- voidsetContext(java.lang.String context) - -
-          Set's the UI reference that caused this ValidationException
- - - - - - - -
Methods inherited from class org.owasp.esapi.errors.EnterpriseSecurityException
getLogMessage, getUserMessage
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-ValidationException

-
-public ValidationException(java.lang.String userMessage,
-                           java.lang.String logMessage)
-
-
Creates a new instance of ValidationException. -

-

-
- -

-ValidationException

-
-public ValidationException(java.lang.String userMessage,
-                           java.lang.String logMessage,
-                           java.lang.Throwable cause)
-
-
Instantiates a new ValidationException. -

-

Parameters:
cause - the cause
-
- -

-ValidationException

-
-public ValidationException(java.lang.String userMessage,
-                           java.lang.String logMessage,
-                           java.lang.String context)
-
-
Creates a new instance of ValidationException. -

-

Parameters:
context - the source that caused this exception
-
- -

-ValidationException

-
-public ValidationException(java.lang.String userMessage,
-                           java.lang.String logMessage,
-                           java.lang.Throwable cause,
-                           java.lang.String context)
-
-
Instantiates a new ValidationException. -

-

Parameters:
cause - the cause
context - the source that caused this exception
- - - - - - - - -
-Method Detail
- -

-getSerialVersionUID

-
-public static long getSerialVersionUID()
-
-
-
-
-
-
- -

-getContext

-
-public java.lang.String getContext()
-
-
Returns the UI reference that caused this ValidationException -

-

- -
Returns:
-
-
-
- -

-setContext

-
-public void setContext(java.lang.String context)
-
-
Set's the UI reference that caused this ValidationException -

-

-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/ValidationUploadException.html b/javadoc/org/owasp/esapi/errors/ValidationUploadException.html deleted file mode 100644 index 7604a3335..000000000 --- a/javadoc/org/owasp/esapi/errors/ValidationUploadException.html +++ /dev/null @@ -1,282 +0,0 @@ - - - - - - -ValidationUploadException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.errors -
-Class ValidationUploadException

-
-java.lang.Object
-  extended byjava.lang.Throwable
-      extended byjava.lang.Exception
-          extended byorg.owasp.esapi.errors.EnterpriseSecurityException
-              extended byorg.owasp.esapi.errors.ValidationException
-                  extended byorg.owasp.esapi.errors.ValidationUploadException
-
-
-
All Implemented Interfaces:
java.io.Serializable
-
-
-
-
public class ValidationUploadException
extends ValidationException
- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
Serialized Form
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
ValidationUploadException(java.lang.String userMessage, - java.lang.String logMessage) - -
-          Create a new ValidationException
ValidationUploadException(java.lang.String userMessage, - java.lang.String logMessage, - java.lang.Throwable cause) - -
-          Create a new ValidationException
-  - - - - - - - - - - -
Methods inherited from class org.owasp.esapi.errors.ValidationException
getContext, getSerialVersionUID, setContext
- - - - - - - -
Methods inherited from class org.owasp.esapi.errors.EnterpriseSecurityException
getLogMessage, getUserMessage
- - - - - - - -
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-ValidationUploadException

-
-public ValidationUploadException(java.lang.String userMessage,
-                                 java.lang.String logMessage)
-
-
Create a new ValidationException -

-

Parameters:
userMessage -
logMessage -
-
- -

-ValidationUploadException

-
-public ValidationUploadException(java.lang.String userMessage,
-                                 java.lang.String logMessage,
-                                 java.lang.Throwable cause)
-
-
Create a new ValidationException -

-

Parameters:
userMessage -
logMessage -
cause -
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/class-use/AccessControlException.html b/javadoc/org/owasp/esapi/errors/class-use/AccessControlException.html deleted file mode 100644 index 31d7e2d14..000000000 --- a/javadoc/org/owasp/esapi/errors/class-use/AccessControlException.html +++ /dev/null @@ -1,404 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.errors.AccessControlException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.errors.AccessControlException

-
- - - - - - - - - - - - - -
-Packages that use AccessControlException
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of AccessControlException in org.owasp.esapi
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi that throw AccessControlException
- voidHTTPUtilities.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.
- voidHTTPUtilities.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.ObjectAccessReferenceMap.getDirectReference(java.lang.String indirectReference) - -
-          Get the original direct object reference from an indirect reference.
- java.lang.StringAccessReferenceMap.removeDirectReference(java.lang.Object direct) - -
-          Removes a direct reference and its associated indirect reference from the AccessReferenceMap.
- voidAccessController.assertAuthorizedForURL(java.lang.String url) - -
-          Checks if an account is authorized to access the referenced URL.
- voidAccessController.assertAuthorizedForFunction(java.lang.String functionName) - -
-          Checks if an account is authorized to access the referenced function.
- voidAccessController.assertAuthorizedForData(java.lang.String key) - -
-          Checks if an account is authorized to access the referenced data.
- voidAccessController.assertAuthorizedForFile(java.lang.String filepath) - -
-          Checks if an account is authorized to access the referenced file.
- voidAccessController.assertAuthorizedForService(java.lang.String serviceName) - -
-          Checks if an account is authorized to access the referenced service.
-  -

- - - - - -
-Uses of AccessControlException in org.owasp.esapi.reference
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi.reference that throw AccessControlException
- java.lang.StringRandomAccessReferenceMap.removeDirectReference(java.lang.Object direct) - -
-          Remove a direct reference and the corresponding indirect reference.
- java.lang.ObjectRandomAccessReferenceMap.getDirectReference(java.lang.String indirectReference) - -
-           
- java.lang.StringIntegerAccessReferenceMap.removeDirectReference(java.lang.Object direct) - -
-          Remove a direct reference and the corresponding indirect reference.
- java.lang.ObjectIntegerAccessReferenceMap.getDirectReference(java.lang.String indirectReference) - -
-           
- voidFileBasedAccessController.assertAuthorizedForURL(java.lang.String url) - -
-           
- voidFileBasedAccessController.assertAuthorizedForFunction(java.lang.String functionName) - -
-           
- voidFileBasedAccessController.assertAuthorizedForData(java.lang.String key) - -
-           
- voidFileBasedAccessController.assertAuthorizedForFile(java.lang.String filepath) - -
-           
- voidFileBasedAccessController.assertAuthorizedForService(java.lang.String serviceName) - -
-           
- voidDefaultHTTPUtilities.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.
- voidDefaultHTTPUtilities.safeSendForward(javax.servlet.http.HttpServletRequest request, - javax.servlet.http.HttpServletResponse response, - java.lang.String context, - java.lang.String location) - -
-           
- voidIntegerAccessReferenceMapTest.testGetDirectReference() - -
-          Test of getDirectReference method, of class - org.owasp.esapi.AccessReferenceMap.
- voidIntegerAccessReferenceMapTest.testAddDirectReference() - -
-           
- voidIntegerAccessReferenceMapTest.testRemoveDirectReference() - -
-           
- voidAccessReferenceMapTest.testGetDirectReference() - -
-          Test of getDirectReference method, of class - org.owasp.esapi.AccessReferenceMap.
- voidAccessReferenceMapTest.testAddDirectReference() - -
-           
- voidAccessReferenceMapTest.testRemoveDirectReference() - -
-           
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/class-use/AuthenticationAccountsException.html b/javadoc/org/owasp/esapi/errors/class-use/AuthenticationAccountsException.html deleted file mode 100644 index 3adaeb3b2..000000000 --- a/javadoc/org/owasp/esapi/errors/class-use/AuthenticationAccountsException.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.errors.AuthenticationAccountsException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.errors.AuthenticationAccountsException

-
-No usage of org.owasp.esapi.errors.AuthenticationAccountsException -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/class-use/AuthenticationCredentialsException.html b/javadoc/org/owasp/esapi/errors/class-use/AuthenticationCredentialsException.html deleted file mode 100644 index 759003168..000000000 --- a/javadoc/org/owasp/esapi/errors/class-use/AuthenticationCredentialsException.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.errors.AuthenticationCredentialsException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.errors.AuthenticationCredentialsException

-
-No usage of org.owasp.esapi.errors.AuthenticationCredentialsException -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/class-use/AuthenticationException.html b/javadoc/org/owasp/esapi/errors/class-use/AuthenticationException.html deleted file mode 100644 index 924d40a01..000000000 --- a/javadoc/org/owasp/esapi/errors/class-use/AuthenticationException.html +++ /dev/null @@ -1,790 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.errors.AuthenticationException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.errors.AuthenticationException

-
- - - - - - - - - - - - - - - - - -
-Packages that use AuthenticationException
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.errorsA set of exception classes designed to model the error conditions that -frequently arise in enterprise web applications and web services. 
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of AuthenticationException in org.owasp.esapi
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi that throw AuthenticationException
- voidUser.addRole(java.lang.String role) - -
-          Adds a role to an account.
- voidUser.addRoles(java.util.Set newRoles) - -
-          Adds a set of roles to an account.
- voidUser.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.DateUser.getLastFailedLoginTime() - -
-          Returns the date of the last failed login time for a user.
- voidUser.loginWithPassword(java.lang.String password) - -
-          Login with password.
- voidUser.removeRole(java.lang.String role) - -
-          Removes a role from an account.
- java.lang.StringUser.resetCSRFToken() - -
-          Returns a token to be used as a prevention against CSRF attacks.
- voidUser.setRoles(java.util.Set roles) - -
-          Sets the roles of this account.
- javax.servlet.http.HttpSessionHTTPUtilities.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.
- UserAuthenticator.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.
- UserAuthenticator.createUser(java.lang.String accountName, - java.lang.String password1, - java.lang.String password2) - -
-          Creates a new User with the information provided.
- voidAuthenticator.changePassword(User user, - java.lang.String currentPassword, - java.lang.String newPassword, - java.lang.String newPassword2) - -
-          Changes the password for the specified user.
- voidAuthenticator.removeUser(java.lang.String accountName) - -
-          Removes the account.
- voidAuthenticator.verifyAccountNameStrength(java.lang.String accountName) - -
-          Ensures that the account name passes site-specific complexity requirements, like minimum length.
- voidAuthenticator.verifyPasswordStrength(java.lang.String oldPassword, - java.lang.String newPassword) - -
-          Ensures that the password meets site-specific complexity requirements.
-  -

- - - - - -
-Uses of AuthenticationException in org.owasp.esapi.errors
-  -

- - - - - - - - - - - - - - - - - - - - - -
Subclasses of AuthenticationException in org.owasp.esapi.errors
- classAuthenticationAccountsException - -
-          An AuthenticationException should be thrown when anything goes wrong during - login or logout.
- classAuthenticationCredentialsException - -
-          An AuthenticationException should be thrown when anything goes wrong during - login or logout.
- classAuthenticationHostException - -
-          An AuthenticationHostException should be thrown when there is a problem with - the host involved with authentication, particularly if the host changes unexpectedly.
- classAuthenticationLoginException - -
-          An AuthenticationException should be thrown when anything goes wrong during - login or logout.
-  -

- - - - - -
-Uses of AuthenticationException in org.owasp.esapi.reference
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi.reference that throw AuthenticationException
- UserFileBasedAuthenticator.createUser(java.lang.String accountName, - java.lang.String password1, - java.lang.String password2) - -
-           
- voidFileBasedAuthenticator.changePassword(User user, - java.lang.String currentPassword, - java.lang.String newPassword, - java.lang.String newPassword2) - -
-           
- voidFileBasedAuthenticator.removeUser(java.lang.String accountName) - -
-           
- UserFileBasedAuthenticator.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.
- voidFileBasedAuthenticator.verifyAccountNameStrength(java.lang.String newAccountName) - -
-           
- voidFileBasedAuthenticator.verifyPasswordStrength(java.lang.String oldPassword, - java.lang.String newPassword) - -
-           
- voidDefaultUser.addRole(java.lang.String role) - -
-           
- voidDefaultUser.addRoles(java.util.Set newRoles) - -
-           
- voidDefaultUser.changePassword(java.lang.String oldPassword, - java.lang.String newPassword1, - java.lang.String newPassword2) - -
-           
- voidDefaultUser.loginWithPassword(java.lang.String password) - -
-           
- voidDefaultUser.setRoles(java.util.Set roles) - -
-          Sets the roles.
- javax.servlet.http.HttpSessionDefaultHTTPUtilities.changeSessionIdentifier(javax.servlet.http.HttpServletRequest request) - -
-           
- voidUserTest.testAddRoles() - -
-          Test of addRoles method, of class org.owasp.esapi.User.
- voidUserTest.testDisable() - -
-          Test of disable method, of class org.owasp.esapi.User.
- voidUserTest.testEnable() - -
-          Test of enable method, of class org.owasp.esapi.User.
- voidUserTest.testFailedLoginLockout() - -
-          Test of failedLoginCount lockout, of class org.owasp.esapi.User.
- voidUserTest.testGetAccountName() - -
-          Test of getAccountName method, of class org.owasp.esapi.User.
- voidUserTest.testGetScreenName() - -
-          Test of xxx method, of class org.owasp.esapi.User.
- voidUserTest.testIncrementFailedLoginCount() - -
-          Test of incrementFailedLoginCount method, of class org.owasp.esapi.User.
- voidUserTest.testIsEnabled() - -
-          Test of isEnabled method, of class org.owasp.esapi.User.
- voidUserTest.testIsInRole() - -
-          Test of isInRole method, of class org.owasp.esapi.User.
- voidUserTest.testIsLocked() - -
-          Test of xxx method, of class org.owasp.esapi.User.
- voidUserTest.testIsSessionAbsoluteTimeout() - -
-          Test of isSessionAbsoluteTimeout method, of class - org.owasp.esapi.IntrusionDetector.
- voidUserTest.testIsSessionTimeout() - -
-          Test of isSessionTimeout method, of class - org.owasp.esapi.IntrusionDetector.
- voidUserTest.testLock() - -
-          Test of lockAccount method, of class org.owasp.esapi.User.
- voidUserTest.testLoginWithPassword() - -
-          Test of loginWithPassword method, of class org.owasp.esapi.User.
- voidUserTest.testLogout() - -
-          Test of logout method, of class org.owasp.esapi.User.
- voidUserTest.testRemoveRole() - -
-          Test of testRemoveRole method, of class org.owasp.esapi.User.
- voidUserTest.testResetCSRFToken() - -
-          Test of testResetCSRFToken method, of class org.owasp.esapi.User.
- voidUserTest.testSetAccountName() - -
-          Test of setAccountName method, of class org.owasp.esapi.User.
- voidUserTest.testSetRoles() - -
-          Test of setRoles method, of class org.owasp.esapi.User.
- voidUserTest.testSetScreenName() - -
-          Test of setScreenName method, of class org.owasp.esapi.User.
- voidUserTest.testUnlock() - -
-          Test of unlockAccount method, of class org.owasp.esapi.User.
- voidLoggerTest.testLogHTTPRequest() - -
-          Test of logHTTPRequest method, of class org.owasp.esapi.Logger.
- voidIntrusionDetectorTest.testAddException() - -
-          Test of addException method, of class org.owasp.esapi.IntrusionDetector.
- voidIntrusionDetectorTest.testAddEvent() - -
-          Test of addEvent method, of class org.owasp.esapi.IntrusionDetector.
- voidIntegerAccessReferenceMapTest.testUpdate() - -
-          Test of update method, of class org.owasp.esapi.AccessReferenceMap.
- voidHTTPUtilitiesTest.testAddCSRFToken() - -
-          Test of addCSRFToken method, of class org.owasp.esapi.HTTPUtilities.
- voidHTTPUtilitiesTest.testSetRememberToken() - -
-           
- voidAuthenticatorTest.testCreateUser() - -
-          Test of createAccount method, of class org.owasp.esapi.Authenticator.
- voidAuthenticatorTest.testGenerateStrongPassword() - -
-          Test of generateStrongPassword method, of class - org.owasp.esapi.Authenticator.
- voidAuthenticatorTest.testGetUser() - -
-          Test of getUser method, of class org.owasp.esapi.Authenticator.
- voidAuthenticatorTest.testGetUserFromRememberToken() - -
-           
- voidAuthenticatorTest.testGetUserFromSession() - -
-          Test get user from session.
- voidAuthenticatorTest.testGetUserNames() - -
-          Test get user names.
- voidAuthenticatorTest.testLogin() - -
-          Test of login method, of class org.owasp.esapi.Authenticator.
- voidAuthenticatorTest.testSetCurrentUser() - -
-          Test of setCurrentUser method, of class org.owasp.esapi.Authenticator.
- voidAuthenticatorTest.testSetCurrentUserWithRequest() - -
-          Test of setCurrentUser method, of class org.owasp.esapi.Authenticator.
- voidAuthenticatorTest.testValidatePasswordStrength() - -
-          Test of validatePasswordStrength method, of class - org.owasp.esapi.Authenticator.
- voidAccessReferenceMapTest.testUpdate() - -
-          Test of update method, of class org.owasp.esapi.AccessReferenceMap.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/class-use/AuthenticationHostException.html b/javadoc/org/owasp/esapi/errors/class-use/AuthenticationHostException.html deleted file mode 100644 index 9b4cf20e8..000000000 --- a/javadoc/org/owasp/esapi/errors/class-use/AuthenticationHostException.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.errors.AuthenticationHostException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.errors.AuthenticationHostException

-
-No usage of org.owasp.esapi.errors.AuthenticationHostException -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/class-use/AuthenticationLoginException.html b/javadoc/org/owasp/esapi/errors/class-use/AuthenticationLoginException.html deleted file mode 100644 index a4e0b607c..000000000 --- a/javadoc/org/owasp/esapi/errors/class-use/AuthenticationLoginException.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.errors.AuthenticationLoginException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.errors.AuthenticationLoginException

-
-No usage of org.owasp.esapi.errors.AuthenticationLoginException -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/class-use/AvailabilityException.html b/javadoc/org/owasp/esapi/errors/class-use/AvailabilityException.html deleted file mode 100644 index 1548def79..000000000 --- a/javadoc/org/owasp/esapi/errors/class-use/AvailabilityException.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.errors.AvailabilityException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.errors.AvailabilityException

-
-No usage of org.owasp.esapi.errors.AvailabilityException -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/class-use/CertificateException.html b/javadoc/org/owasp/esapi/errors/class-use/CertificateException.html deleted file mode 100644 index d38ce80e2..000000000 --- a/javadoc/org/owasp/esapi/errors/class-use/CertificateException.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.errors.CertificateException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.errors.CertificateException

-
-No usage of org.owasp.esapi.errors.CertificateException -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/class-use/EncodingException.html b/javadoc/org/owasp/esapi/errors/class-use/EncodingException.html deleted file mode 100644 index 0c1395e42..000000000 --- a/javadoc/org/owasp/esapi/errors/class-use/EncodingException.html +++ /dev/null @@ -1,244 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.errors.EncodingException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.errors.EncodingException

-
- - - - - - - - - - - - - -
-Packages that use EncodingException
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of EncodingException in org.owasp.esapi
-  -

- - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi that throw EncodingException
- java.lang.StringEncoder.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.StringEncoder.canonicalize(java.lang.String input, - boolean strict) - -
-           
- java.lang.StringEncoder.encodeForURL(java.lang.String input) - -
-          Encode for use in a URL.
- java.lang.StringEncoder.decodeFromURL(java.lang.String input) - -
-          Decode from URL.
-  -

- - - - - -
-Uses of EncodingException in org.owasp.esapi.reference
-  -

- - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi.reference that throw EncodingException
- java.lang.StringDefaultEncoder.encodeForURL(java.lang.String input) - -
-           
- java.lang.StringDefaultEncoder.decodeFromURL(java.lang.String input) - -
-           
- voidEncoderTest.testCanonicalize() - -
-          Test of canonicalize method, of class org.owasp.esapi.Encoder.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/class-use/EncryptionException.html b/javadoc/org/owasp/esapi/errors/class-use/EncryptionException.html deleted file mode 100644 index 08958e589..000000000 --- a/javadoc/org/owasp/esapi/errors/class-use/EncryptionException.html +++ /dev/null @@ -1,549 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.errors.EncryptionException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.errors.EncryptionException

-
- - - - - - - - - - - - - -
-Packages that use EncryptionException
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of EncryptionException in org.owasp.esapi
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi that throw EncryptionException
- voidUser.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.
- booleanUser.verifyPassword(java.lang.String password) - -
-          Verify that the supplied password matches the password for this user.
- java.lang.StringRandomizer.getRandomGUID() - -
-          Generates a random GUID.
- java.lang.StringHTTPUtilities.encryptHiddenField(java.lang.String value) - -
-          Encrypts a hidden field value for use in HTML.
- java.lang.StringHTTPUtilities.encryptQueryString(java.lang.String query) - -
-          Takes a querystring (i.e.
- java.util.MapHTTPUtilities.decryptQueryString(java.lang.String encrypted) - -
-          Takes an encrypted querystring and returns a Map containing the original parameters.
- java.util.MapHTTPUtilities.decryptStateFromCookie(javax.servlet.http.HttpServletRequest request) - -
-          Retrieves a map of data from a cookie encrypted with encryptStateInCookie().
- voidHTTPUtilities.encryptStateInCookie(javax.servlet.http.HttpServletResponse response, - java.util.Map cleartext) - -
-          Stores a Map of data in an encrypted cookie.
- java.lang.StringEncryptor.hash(java.lang.String plaintext, - java.lang.String salt) - -
-          Returns a string representation of the hash of the provided plaintext and - salt.
- java.lang.StringEncryptor.encrypt(java.lang.String plaintext) - -
-          Encrypts the provided plaintext and returns a ciphertext string.
- java.lang.StringEncryptor.decrypt(java.lang.String ciphertext) - -
-          Decrypts the provided ciphertext string (encrypted with the encrypt - method) and returns a plaintext string.
- java.lang.StringEncryptor.sign(java.lang.String data) - -
-          Create a digital signature for the provided data and return it in a - string.
- java.lang.StringEncryptor.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.StringEncryptedProperties.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.StringEncryptedProperties.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.StringAuthenticator.hashPassword(java.lang.String password, - java.lang.String accountName) - -
-          Returns a string representation of the hashed password, using the - accountName as the salt.
-  -

- - - - - -
-Uses of EncryptionException in org.owasp.esapi.reference
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi.reference that throw EncryptionException
- java.lang.StringJavaEncryptor.hash(java.lang.String plaintext, - java.lang.String salt) - -
-          Hashes the data using the specified algorithm and the Java MessageDigest class.
- java.lang.StringJavaEncryptor.encrypt(java.lang.String plaintext) - -
-           
- java.lang.StringJavaEncryptor.decrypt(java.lang.String ciphertext) - -
-           
- java.lang.StringJavaEncryptor.sign(java.lang.String data) - -
-           
- java.lang.StringJavaEncryptor.unseal(java.lang.String seal) - -
-           
- java.lang.StringFileBasedAuthenticator.hashPassword(java.lang.String password, - java.lang.String accountName) - -
-           
- voidDefaultUser.changePassword(java.lang.String oldPassword, - java.lang.String newPassword1, - java.lang.String newPassword2) - -
-           
- java.lang.StringDefaultRandomizer.getRandomGUID() - -
-           
- java.util.MapDefaultHTTPUtilities.decryptQueryString(java.lang.String encrypted) - -
-           
- java.util.MapDefaultHTTPUtilities.decryptStateFromCookie(javax.servlet.http.HttpServletRequest request) - -
-           
- java.lang.StringDefaultHTTPUtilities.encryptHiddenField(java.lang.String value) - -
-           
- java.lang.StringDefaultHTTPUtilities.encryptQueryString(java.lang.String query) - -
-           
- voidDefaultHTTPUtilities.encryptStateInCookie(javax.servlet.http.HttpServletResponse response, - java.util.Map cleartext) - -
-           
- java.lang.StringDefaultEncryptedProperties.getProperty(java.lang.String key) - -
-           
- java.lang.StringDefaultEncryptedProperties.setProperty(java.lang.String key, - java.lang.String value) - -
-           
- voidUserTest.testFailedLoginLockout() - -
-          Test of failedLoginCount lockout, of class org.owasp.esapi.User.
- voidRandomizerTest.testGetRandomGUID() - -
-          Test of getRandomGUID method, of class org.owasp.esapi.Randomizer.
- voidIntegerAccessReferenceMapTest.testUpdate() - -
-          Test of update method, of class org.owasp.esapi.AccessReferenceMap.
- voidEncryptorTest.testHash() - -
-          Test of hash method, of class org.owasp.esapi.Encryptor.
- voidEncryptorTest.testEncrypt() - -
-          Test of encrypt method, of class org.owasp.esapi.Encryptor.
- voidEncryptorTest.testSign() - -
-          Test of sign method, of class org.owasp.esapi.Encryptor.
- voidEncryptorTest.testVerifySignature() - -
-          Test of verifySignature method, of class org.owasp.esapi.Encryptor.
- voidEncryptedPropertiesTest.testGetProperty() - -
-          Test of getProperty method, of class org.owasp.esapi.EncryptedProperties.
- voidEncryptedPropertiesTest.testSetProperty() - -
-          Test of setProperty method, of class org.owasp.esapi.EncryptedProperties.
- voidAuthenticatorTest.testCreateUser() - -
-          Test of createAccount method, of class org.owasp.esapi.Authenticator.
- voidAuthenticatorTest.testHashPassword() - -
-          Test of hashPassword method, of class org.owasp.esapi.Authenticator.
- voidAccessReferenceMapTest.testUpdate() - -
-          Test of update method, of class org.owasp.esapi.AccessReferenceMap.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/class-use/EnterpriseSecurityException.html b/javadoc/org/owasp/esapi/errors/class-use/EnterpriseSecurityException.html deleted file mode 100644 index c49f0852b..000000000 --- a/javadoc/org/owasp/esapi/errors/class-use/EnterpriseSecurityException.html +++ /dev/null @@ -1,336 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.errors.EnterpriseSecurityException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.errors.EnterpriseSecurityException

-
- - - - - - - - - - - - - -
-Packages that use EnterpriseSecurityException
org.owasp.esapi.errorsA set of exception classes designed to model the error conditions that -frequently arise in enterprise web applications and web services. 
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of EnterpriseSecurityException in org.owasp.esapi.errors
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Subclasses of EnterpriseSecurityException in org.owasp.esapi.errors
- classAccessControlException - -
-          An AccessControlException should be thrown when a user attempts to access a - resource that they are not authorized for.
- classAuthenticationAccountsException - -
-          An AuthenticationException should be thrown when anything goes wrong during - login or logout.
- classAuthenticationCredentialsException - -
-          An AuthenticationException should be thrown when anything goes wrong during - login or logout.
- classAuthenticationException - -
-          An AuthenticationException should be thrown when anything goes wrong during - login or logout.
- classAuthenticationHostException - -
-          An AuthenticationHostException should be thrown when there is a problem with - the host involved with authentication, particularly if the host changes unexpectedly.
- classAuthenticationLoginException - -
-          An AuthenticationException should be thrown when anything goes wrong during - login or logout.
- classAvailabilityException - -
-          An AvailabilityException should be thrown when the availability of a limited - resource is in jeopardy.
- classCertificateException - -
-          A CertificateException should be thrown for any problems that arise during - processing of digital certificates.
- classEncodingException - -
-          An ExecutorException should be thrown for any problems that occur when - encoding or decoding data.
- classEncryptionException - -
-          An EncryptionException should be thrown for any problems related to - encryption, hashing, or digital signatures.
- classExecutorException - -
-          An ExecutorException should be thrown for any problems that arise during the - execution of a system executable.
- classIntegrityException - -
-          An AvailabilityException should be thrown when the availability of a limited - resource is in jeopardy.
- classValidationAvailabilityException - -
-           
- classValidationException - -
-          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.
- classValidationUploadException - -
-           
-  -

- - - - - -
-Uses of EnterpriseSecurityException in org.owasp.esapi.reference
-  -

- - - - - - - - - - - - - -
Methods in org.owasp.esapi.reference that throw EnterpriseSecurityException
- voidHTTPUtilitiesTest.testChangeSessionIdentifier() - -
-          Test of sendRedirect method, of class org.owasp.esapi.HTTPUtilities.
- voidEncryptorTest.testVerifySeal() - -
-          Test of verifySeal method, of class org.owasp.esapi.Encryptor.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/class-use/EnterpriseSecurityExceptionTest.html b/javadoc/org/owasp/esapi/errors/class-use/EnterpriseSecurityExceptionTest.html deleted file mode 100644 index 30d42e8c7..000000000 --- a/javadoc/org/owasp/esapi/errors/class-use/EnterpriseSecurityExceptionTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.errors.EnterpriseSecurityExceptionTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.errors.EnterpriseSecurityExceptionTest

-
-No usage of org.owasp.esapi.errors.EnterpriseSecurityExceptionTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/class-use/ExecutorException.html b/javadoc/org/owasp/esapi/errors/class-use/ExecutorException.html deleted file mode 100644 index d9b76180b..000000000 --- a/javadoc/org/owasp/esapi/errors/class-use/ExecutorException.html +++ /dev/null @@ -1,210 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.errors.ExecutorException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.errors.ExecutorException

-
- - - - - - - - - - - - - -
-Packages that use ExecutorException
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of ExecutorException in org.owasp.esapi
-  -

- - - - - - - - - -
Methods in org.owasp.esapi that throw ExecutorException
- java.lang.StringExecutor.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.
-  -

- - - - - -
-Uses of ExecutorException in org.owasp.esapi.reference
-  -

- - - - - - - - - -
Methods in org.owasp.esapi.reference that throw ExecutorException
- java.lang.StringDefaultExecutor.executeSystemCommand(java.io.File executable, - java.util.List params, - java.io.File workdir, - int timeoutSeconds) - -
-           
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/class-use/IntegrityException.html b/javadoc/org/owasp/esapi/errors/class-use/IntegrityException.html deleted file mode 100644 index 8ee2272a6..000000000 --- a/javadoc/org/owasp/esapi/errors/class-use/IntegrityException.html +++ /dev/null @@ -1,212 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.errors.IntegrityException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.errors.IntegrityException

-
- - - - - - - - - - - - - -
-Packages that use IntegrityException
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of IntegrityException in org.owasp.esapi
-  -

- - - - - - - - - -
Methods in org.owasp.esapi that throw IntegrityException
- java.lang.StringEncryptor.seal(java.lang.String data, - long timestamp) - -
-          Creates a seal that binds a set of data and includes an expiration timestamp.
-  -

- - - - - -
-Uses of IntegrityException in org.owasp.esapi.reference
-  -

- - - - - - - - - - - - - -
Methods in org.owasp.esapi.reference that throw IntegrityException
- java.lang.StringJavaEncryptor.seal(java.lang.String data, - long expiration) - -
-           
- voidEncryptorTest.testSeal() - -
-          Test of seal method, of class org.owasp.esapi.Encryptor.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/class-use/IntrusionException.html b/javadoc/org/owasp/esapi/errors/class-use/IntrusionException.html deleted file mode 100644 index 6abff3a46..000000000 --- a/javadoc/org/owasp/esapi/errors/class-use/IntrusionException.html +++ /dev/null @@ -1,1324 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.errors.IntrusionException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.errors.IntrusionException

-
- - - - - - - - - - - - - -
-Packages that use IntrusionException
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of IntrusionException in org.owasp.esapi
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi that throw IntrusionException
- booleanValidator.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.StringValidator.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.StringValidator.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.
- booleanValidator.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.DateValidator.getValidDate(java.lang.String context, - java.lang.String input, - java.text.DateFormat format, - boolean allowNull) - -
-          Returns a valid date as a Date.
- java.util.DateValidator.getValidDate(java.lang.String context, - java.lang.String input, - java.text.DateFormat format, - boolean allowNull, - ValidationErrorList errorList) - -
-          Returns a valid date as a Date.
- booleanValidator.isValidSafeHTML(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-          Returns true if input is "safe" HTML.
- java.lang.StringValidator.getValidSafeHTML(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-          Returns canonicalized and validated "safe" HTML.
- java.lang.StringValidator.getValidSafeHTML(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull, - ValidationErrorList errorList) - -
-          Returns canonicalized and validated "safe" HTML.
- booleanValidator.isValidCreditCard(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns true if input is a valid credit card.
- java.lang.StringValidator.getValidCreditCard(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated credit card number as a String.
- java.lang.StringValidator.getValidCreditCard(java.lang.String context, - java.lang.String input, - boolean allowNull, - ValidationErrorList errorList) - -
-          Returns a canonicalized and validated credit card number as a String.
- booleanValidator.isValidDirectoryPath(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns true if input is a valid directory path.
- java.lang.StringValidator.getValidDirectoryPath(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated directory path as a String.
- java.lang.StringValidator.getValidDirectoryPath(java.lang.String context, - java.lang.String input, - boolean allowNull, - ValidationErrorList errorList) - -
-          Returns a canonicalized and validated directory path as a String.
- booleanValidator.isValidFileName(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns true if input is a valid file name.
- java.lang.StringValidator.getValidFileName(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated file name as a String.
- java.lang.StringValidator.getValidFileName(java.lang.String context, - java.lang.String input, - boolean allowNull, - ValidationErrorList errorList) - -
-          Returns a canonicalized and validated file name as a String.
- booleanValidator.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.DoubleValidator.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.DoubleValidator.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.
- booleanValidator.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.IntegerValidator.getValidInteger(java.lang.String context, - java.lang.String input, - int minValue, - int maxValue, - boolean allowNull) - -
-          Returns a validated integer.
- java.lang.IntegerValidator.getValidInteger(java.lang.String context, - java.lang.String input, - int minValue, - int maxValue, - boolean allowNull, - ValidationErrorList errorList) - -
-          Returns a validated integer.
- booleanValidator.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.DoubleValidator.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.DoubleValidator.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.
- booleanValidator.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.
- booleanValidator.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.
- voidValidator.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.
- voidValidator.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.
- booleanValidator.isValidHTTPRequest() - -
-          Validate the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed - characters.
- voidValidator.assertIsValidHTTPRequest() - -
-          Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed - characters.
- booleanValidator.isValidListItem(java.lang.String context, - java.lang.String input, - java.util.List list) - -
-          Returns true if input is a valid list item.
- java.lang.StringValidator.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.StringValidator.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.
- booleanValidator.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.
- voidValidator.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.
- voidValidator.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.
- booleanValidator.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.
- booleanValidator.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.StringValidator.getValidPrintable(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull, - ValidationErrorList errorList) - -
-          Returns canonicalized and validated printable characters as a String.
- booleanValidator.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.StringValidator.getValidRedirectLocation(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated redirect location as a String.
- java.lang.StringValidator.getValidRedirectLocation(java.lang.String context, - java.lang.String input, - boolean allowNull, - ValidationErrorList errorList) - -
-          Returns a canonicalized and validated redirect location as a String.
- voidIntrusionDetector.addException(java.lang.Exception exception) - -
-          Adds the exception to the IntrusionDetector.
- voidIntrusionDetector.addEvent(java.lang.String eventName, - java.lang.String logMessage) - -
-          Adds the event to the IntrusionDetector.
- voidHTTPUtilities.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.
-  -

- - - - - -
-Uses of IntrusionException in org.owasp.esapi.reference
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi.reference that throw IntrusionException
- booleanDefaultValidator.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.StringDefaultValidator.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.StringDefaultValidator.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.
- booleanDefaultValidator.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.DateDefaultValidator.getValidDate(java.lang.String context, - java.lang.String input, - java.text.DateFormat format, - boolean allowNull) - -
-           
- java.util.DateDefaultValidator.getValidDate(java.lang.String context, - java.lang.String input, - java.text.DateFormat format, - boolean allowNull, - ValidationErrorList errors) - -
-           
- booleanDefaultValidator.isValidSafeHTML(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-           
- java.lang.StringDefaultValidator.getValidSafeHTML(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-           
- java.lang.StringDefaultValidator.getValidSafeHTML(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull, - ValidationErrorList errors) - -
-          ValidationErrorList variant of getValidSafeHTML
- booleanDefaultValidator.isValidCreditCard(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-           
- java.lang.StringDefaultValidator.getValidCreditCard(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated credit card number as a String.
- java.lang.StringDefaultValidator.getValidCreditCard(java.lang.String context, - java.lang.String input, - boolean allowNull, - ValidationErrorList errors) - -
-          ValidationErrorList variant of getValidCreditCard
- booleanDefaultValidator.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.StringDefaultValidator.getValidDirectoryPath(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated directory path as a String.
- java.lang.StringDefaultValidator.getValidDirectoryPath(java.lang.String context, - java.lang.String input, - boolean allowNull, - ValidationErrorList errors) - -
-          ValidationErrorList variant of getValidDirectoryPath
- booleanDefaultValidator.isValidFileName(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns true if input is a valid file name.
- java.lang.StringDefaultValidator.getValidFileName(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated file name as a String.
- java.lang.StringDefaultValidator.getValidFileName(java.lang.String context, - java.lang.String input, - boolean allowNull, - ValidationErrorList errors) - -
-          Returns a canonicalized and validated file name as a String.
- booleanDefaultValidator.isValidNumber(java.lang.String context, - java.lang.String input, - long minValue, - long maxValue, - boolean allowNull) - -
-           
- java.lang.DoubleDefaultValidator.getValidNumber(java.lang.String context, - java.lang.String input, - long minValue, - long maxValue, - boolean allowNull) - -
-          Returns a validated number as a double.
- java.lang.DoubleDefaultValidator.getValidNumber(java.lang.String context, - java.lang.String input, - long minValue, - long maxValue, - boolean allowNull, - ValidationErrorList errors) - -
-           
- booleanDefaultValidator.isValidDouble(java.lang.String context, - java.lang.String input, - double minValue, - double maxValue, - boolean allowNull) - -
-           
- java.lang.DoubleDefaultValidator.getValidDouble(java.lang.String context, - java.lang.String input, - double minValue, - double maxValue, - boolean allowNull) - -
-          Returns a validated number as a double.
- java.lang.DoubleDefaultValidator.getValidDouble(java.lang.String context, - java.lang.String input, - double minValue, - double maxValue, - boolean allowNull, - ValidationErrorList errors) - -
-           
- booleanDefaultValidator.isValidInteger(java.lang.String context, - java.lang.String input, - int minValue, - int maxValue, - boolean allowNull) - -
-           
- java.lang.IntegerDefaultValidator.getValidInteger(java.lang.String context, - java.lang.String input, - int minValue, - int maxValue, - boolean allowNull) - -
-          Returns a validated number as a double.
- java.lang.IntegerDefaultValidator.getValidInteger(java.lang.String context, - java.lang.String input, - int minValue, - int maxValue, - boolean allowNull, - ValidationErrorList errors) - -
-           
- booleanDefaultValidator.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.
- byte[]DefaultValidator.getValidFileContent(java.lang.String context, - byte[] input, - int maxBytes, - boolean allowNull, - ValidationErrorList errors) - -
-           
- booleanDefaultValidator.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.
- voidDefaultValidator.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.
- voidDefaultValidator.assertValidFileUpload(java.lang.String context, - java.lang.String filepath, - java.lang.String filename, - byte[] content, - int maxBytes, - boolean allowNull, - ValidationErrorList errors) - -
-          ValidationErrorList variant of assertValidFileUpload
- booleanDefaultValidator.isValidHTTPRequest() - -
-          Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed - characters.
- booleanDefaultValidator.isValidHTTPRequest(javax.servlet.http.HttpServletRequest request) - -
-          Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed - characters.
- voidDefaultValidator.assertIsValidHTTPRequest() - -
-          Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed - characters.
- java.lang.StringDefaultValidator.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.StringDefaultValidator.getValidListItem(java.lang.String context, - java.lang.String input, - java.util.List list, - ValidationErrorList errors) - -
-          ValidationErrorList variant of getValidListItem
- voidDefaultValidator.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.
- voidDefaultValidator.assertIsValidHTTPRequestParameterSet(java.lang.String context, - java.util.Set required, - java.util.Set optional, - ValidationErrorList errors) - -
-          ValidationErrorList variant of assertIsValidHTTPRequestParameterSet
- booleanDefaultValidator.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.
- byte[]DefaultValidator.getValidPrintable(java.lang.String context, - byte[] input, - int maxLength, - boolean allowNull, - ValidationErrorList errors) - -
-          ValidationErrorList variant of getValidPrintable
- booleanDefaultValidator.isValidPrintable(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-           
- java.lang.StringDefaultValidator.getValidPrintable(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-          Returns canonicalized and validated printable characters as a String.
- java.lang.StringDefaultValidator.getValidPrintable(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull, - ValidationErrorList errors) - -
-          ValidationErrorList variant of getValidPrintable
- booleanDefaultValidator.isValidRedirectLocation(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns true if input is a valid redirect location.
- java.lang.StringDefaultValidator.getValidRedirectLocation(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated redirect location as a String.
- java.lang.StringDefaultValidator.getValidRedirectLocation(java.lang.String context, - java.lang.String input, - boolean allowNull, - ValidationErrorList errors) - -
-          ValidationErrorList variant of getValidRedirectLocation
- voidDefaultIntrusionDetector.addEvent(java.lang.String eventName, - java.lang.String logMessage) - -
-          Adds the event to the IntrusionDetector.
- voidDefaultHTTPUtilities.verifyCSRFToken(javax.servlet.http.HttpServletRequest request) - -
-           
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/class-use/ValidationAvailabilityException.html b/javadoc/org/owasp/esapi/errors/class-use/ValidationAvailabilityException.html deleted file mode 100644 index 7b9be6b5e..000000000 --- a/javadoc/org/owasp/esapi/errors/class-use/ValidationAvailabilityException.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.errors.ValidationAvailabilityException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.errors.ValidationAvailabilityException

-
-No usage of org.owasp.esapi.errors.ValidationAvailabilityException -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/class-use/ValidationException.html b/javadoc/org/owasp/esapi/errors/class-use/ValidationException.html deleted file mode 100644 index cd1f55165..000000000 --- a/javadoc/org/owasp/esapi/errors/class-use/ValidationException.html +++ /dev/null @@ -1,728 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.errors.ValidationException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.errors.ValidationException

-
- - - - - - - - - - - - - - - - - -
-Packages that use ValidationException
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.errorsA set of exception classes designed to model the error conditions that -frequently arise in enterprise web applications and web services. 
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of ValidationException in org.owasp.esapi
-  -

- - - - - - - - - -
Methods in org.owasp.esapi that return ValidationException
- ValidationExceptionValidationErrorList.getError(java.lang.String context) - -
-          Retrieves ValidationException for given context if one exists.
-  -

- - - - - - - - - -
Methods in org.owasp.esapi with parameters of type ValidationException
- voidValidationErrorList.addError(java.lang.String context, - ValidationException ve) - -
-          Adds a new error to list with a unique named context.
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi that throw ValidationException
- java.lang.StringValidator.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.DateValidator.getValidDate(java.lang.String context, - java.lang.String input, - java.text.DateFormat format, - boolean allowNull) - -
-          Returns a valid date as a Date.
- java.lang.StringValidator.getValidSafeHTML(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-          Returns canonicalized and validated "safe" HTML.
- java.lang.StringValidator.getValidCreditCard(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated credit card number as a String.
- java.lang.StringValidator.getValidDirectoryPath(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated directory path as a String.
- java.lang.StringValidator.getValidFileName(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated file name as a String.
- java.lang.DoubleValidator.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.IntegerValidator.getValidInteger(java.lang.String context, - java.lang.String input, - int minValue, - int maxValue, - boolean allowNull) - -
-          Returns a validated integer.
- java.lang.DoubleValidator.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.
- voidValidator.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.
- voidValidator.assertIsValidHTTPRequest() - -
-          Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed - characters.
- java.lang.StringValidator.getValidListItem(java.lang.String context, - java.lang.String input, - java.util.List list) - -
-          Returns the list item that exactly matches the canonicalized input.
- voidValidator.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.StringValidator.getValidPrintable(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-          Returns canonicalized and validated printable characters as a String.
- java.lang.StringValidator.getValidRedirectLocation(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated redirect location as a String.
- java.lang.StringValidator.safeReadLine(java.io.InputStream inputStream, - int maxLength) - -
-          Reads from an input stream until end-of-line or a maximum number of - characters.
- java.util.ListHTTPUtilities.getSafeFileUploads(javax.servlet.http.HttpServletRequest request, - java.io.File tempDir, - java.io.File finalDir) - -
-          Extract uploaded files from a multipart HTTP requests.
-  -

- - - - - - - - - - - - - - - - - -
Constructors in org.owasp.esapi that throw ValidationException
SafeFile(java.lang.String path) - -
-           
SafeFile(java.lang.String parent, - java.lang.String child) - -
-           
SafeFile(java.io.File parent, - java.lang.String child) - -
-           
SafeFile(java.net.URI uri) - -
-           
-  -

- - - - - -
-Uses of ValidationException in org.owasp.esapi.errors
-  -

- - - - - - - - - - - - - -
Subclasses of ValidationException in org.owasp.esapi.errors
- classValidationAvailabilityException - -
-           
- classValidationUploadException - -
-           
-  -

- - - - - -
-Uses of ValidationException in org.owasp.esapi.reference
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi.reference that throw ValidationException
- java.lang.StringDefaultValidator.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.util.DateDefaultValidator.getValidDate(java.lang.String context, - java.lang.String input, - java.text.DateFormat format, - boolean allowNull) - -
-           
- java.lang.StringDefaultValidator.getValidSafeHTML(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-           
- java.lang.StringDefaultValidator.getValidCreditCard(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated credit card number as a String.
- java.lang.StringDefaultValidator.getValidDirectoryPath(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated directory path as a String.
- java.lang.StringDefaultValidator.getValidFileName(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated file name as a String.
- java.lang.DoubleDefaultValidator.getValidNumber(java.lang.String context, - java.lang.String input, - long minValue, - long maxValue, - boolean allowNull) - -
-          Returns a validated number as a double.
- java.lang.DoubleDefaultValidator.getValidDouble(java.lang.String context, - java.lang.String input, - double minValue, - double maxValue, - boolean allowNull) - -
-          Returns a validated number as a double.
- java.lang.IntegerDefaultValidator.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.
- voidDefaultValidator.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.
- voidDefaultValidator.assertIsValidHTTPRequest() - -
-          Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed - characters.
- java.lang.StringDefaultValidator.getValidListItem(java.lang.String context, - java.lang.String input, - java.util.List list) - -
-          Returns the list item that exactly matches the canonicalized input.
- voidDefaultValidator.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.StringDefaultValidator.getValidPrintable(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-          Returns canonicalized and validated printable characters as a String.
- java.lang.StringDefaultValidator.getValidRedirectLocation(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated redirect location as a String.
- java.lang.StringDefaultValidator.safeReadLine(java.io.InputStream in, - int max) - -
-          This implementation reads until a newline or the specified number of - characters.
- java.util.ListDefaultHTTPUtilities.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.
- voidLoggerTest.testLogHTTPRequest() - -
-          Test of logHTTPRequest method, of class org.owasp.esapi.Logger.
- voidHTTPUtilitiesTest.testSendSafeRedirect() - -
-          Test of sendRedirect method, of class org.owasp.esapi.HTTPUtilities.
- voidEncoderTest.testNormalize() - -
-          Test of normalize method, of class org.owasp.esapi.Validator.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/class-use/ValidationUploadException.html b/javadoc/org/owasp/esapi/errors/class-use/ValidationUploadException.html deleted file mode 100644 index e7b4055cc..000000000 --- a/javadoc/org/owasp/esapi/errors/class-use/ValidationUploadException.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.errors.ValidationUploadException - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.errors.ValidationUploadException

-
-No usage of org.owasp.esapi.errors.ValidationUploadException -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/package-frame.html b/javadoc/org/owasp/esapi/errors/package-frame.html deleted file mode 100644 index c871df42e..000000000 --- a/javadoc/org/owasp/esapi/errors/package-frame.html +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - -org.owasp.esapi.errors - - - - - - - - - - - -org.owasp.esapi.errors - - - - -
-Classes  - -
-EnterpriseSecurityExceptionTest
- - - - - - -
-Exceptions  - -
-AccessControlException -
-AuthenticationAccountsException -
-AuthenticationCredentialsException -
-AuthenticationException -
-AuthenticationHostException -
-AuthenticationLoginException -
-AvailabilityException -
-CertificateException -
-EncodingException -
-EncryptionException -
-EnterpriseSecurityException -
-ExecutorException -
-IntegrityException -
-IntrusionException -
-ValidationAvailabilityException -
-ValidationException -
-ValidationUploadException
- - - - diff --git a/javadoc/org/owasp/esapi/errors/package-summary.html b/javadoc/org/owasp/esapi/errors/package-summary.html deleted file mode 100644 index 7e98a1c15..000000000 --- a/javadoc/org/owasp/esapi/errors/package-summary.html +++ /dev/null @@ -1,263 +0,0 @@ - - - - - - -org.owasp.esapi.errors - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-

-Package org.owasp.esapi.errors -

-A set of exception classes designed to model the error conditions that -frequently arise in enterprise web applications and web services. -

-See: -
-          Description -

- - - - - - - - - -
-Class Summary
EnterpriseSecurityExceptionTestThe Class AccessReferenceMapTest.
-  - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Exception Summary
AccessControlExceptionAn AccessControlException should be thrown when a user attempts to access a - resource that they are not authorized for.
AuthenticationAccountsExceptionAn AuthenticationException should be thrown when anything goes wrong during - login or logout.
AuthenticationCredentialsExceptionAn AuthenticationException should be thrown when anything goes wrong during - login or logout.
AuthenticationExceptionAn AuthenticationException should be thrown when anything goes wrong during - login or logout.
AuthenticationHostExceptionAn AuthenticationHostException should be thrown when there is a problem with - the host involved with authentication, particularly if the host changes unexpectedly.
AuthenticationLoginExceptionAn AuthenticationException should be thrown when anything goes wrong during - login or logout.
AvailabilityExceptionAn AvailabilityException should be thrown when the availability of a limited - resource is in jeopardy.
CertificateExceptionA CertificateException should be thrown for any problems that arise during - processing of digital certificates.
EncodingExceptionAn ExecutorException should be thrown for any problems that occur when - encoding or decoding data.
EncryptionExceptionAn EncryptionException should be thrown for any problems related to - encryption, hashing, or digital signatures.
EnterpriseSecurityExceptionEnterpriseSecurityException is the base class for all security related exceptions.
ExecutorExceptionAn ExecutorException should be thrown for any problems that arise during the - execution of a system executable.
IntegrityExceptionAn AvailabilityException should be thrown when the availability of a limited - resource is in jeopardy.
IntrusionExceptionAn IntrusionException should be thrown anytime an error condition arises that is likely to be the result of an attack - in progress.
ValidationAvailabilityException 
ValidationExceptionA 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.
ValidationUploadException 
-  - -

-

-Package org.owasp.esapi.errors Description -

- -

-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. -

- -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/package-tree.html b/javadoc/org/owasp/esapi/errors/package-tree.html deleted file mode 100644 index cd4f1114c..000000000 --- a/javadoc/org/owasp/esapi/errors/package-tree.html +++ /dev/null @@ -1,163 +0,0 @@ - - - - - - -org.owasp.esapi.errors Class Hierarchy - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Hierarchy For Package org.owasp.esapi.errors -

-
-
-
Package Hierarchies:
All Packages
-
-

-Class Hierarchy -

- -
- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/errors/package-use.html b/javadoc/org/owasp/esapi/errors/package-use.html deleted file mode 100644 index db60d0a5a..000000000 --- a/javadoc/org/owasp/esapi/errors/package-use.html +++ /dev/null @@ -1,325 +0,0 @@ - - - - - - -Uses of Package org.owasp.esapi.errors - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Package
org.owasp.esapi.errors

-
- - - - - - - - - - - - - - - - - -
-Packages that use org.owasp.esapi.errors
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.errorsA set of exception classes designed to model the error conditions that -frequently arise in enterprise web applications and web services. 
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Classes in org.owasp.esapi.errors used by org.owasp.esapi
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.
-  -

- - - - - - - - - - - - - - -
-Classes in org.owasp.esapi.errors used by org.owasp.esapi.errors
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.
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Classes in org.owasp.esapi.errors used by org.owasp.esapi.reference
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.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/filters/ESAPIFilter.html b/javadoc/org/owasp/esapi/filters/ESAPIFilter.html deleted file mode 100644 index c56c6f597..000000000 --- a/javadoc/org/owasp/esapi/filters/ESAPIFilter.html +++ /dev/null @@ -1,331 +0,0 @@ - - - - - - -ESAPIFilter - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.filters -
-Class ESAPIFilter

-
-java.lang.Object
-  extended byorg.owasp.esapi.filters.ESAPIFilter
-
-
-
All Implemented Interfaces:
javax.servlet.Filter
-
-
-
-
public class ESAPIFilter
extends java.lang.Object
implements javax.servlet.Filter
- -

-


- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
ESAPIFilter() - -
-           
-  - - - - - - - - - - - - - - - - - - - -
-Method Summary
- voiddestroy() - -
-          Called by the web container to indicate to a filter that it is being - taken out of service.
- voiddoFilter(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.
- voidinit(javax.servlet.FilterConfig filterConfig) - -
-          Called by the web container to indicate to a filter that it is being - placed into service.
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-ESAPIFilter

-
-public ESAPIFilter()
-
-
- - - - - - - - -
-Method Detail
- -

-init

-
-public void init(javax.servlet.FilterConfig filterConfig)
-
-
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. -

-

-
Specified by:
init in interface javax.servlet.Filter
-
-
-
Parameters:
filterConfig - configuration object
-
-
-
- -

-doFilter

-
-public void doFilter(javax.servlet.ServletRequest req,
-                     javax.servlet.ServletResponse resp,
-                     javax.servlet.FilterChain chain)
-              throws java.io.IOException
-
-
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. -

-

-
Specified by:
destroy in interface javax.servlet.Filter
-
-
-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/filters/ESAPIFilterTest.html b/javadoc/org/owasp/esapi/filters/ESAPIFilterTest.html deleted file mode 100644 index 0e3c5fea0..000000000 --- a/javadoc/org/owasp/esapi/filters/ESAPIFilterTest.html +++ /dev/null @@ -1,313 +0,0 @@ - - - - - - -ESAPIFilterTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.filters -
-Class ESAPIFilterTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.filters.ESAPIFilterTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class ESAPIFilterTest
extends junit.framework.TestCase
- -

-The Class AccessReferenceMapTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
ESAPIFilterTest(java.lang.String testName) - -
-          Instantiates a new access reference map test.
-  - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestFilter() - -
-          Test of update method, of class org.owasp.esapi.AccessReferenceMap.
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-ESAPIFilterTest

-
-public ESAPIFilterTest(java.lang.String testName)
-
-
Instantiates a new access reference map test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testFilter

-
-public void testFilter()
-                throws java.lang.Exception
-
-
Test of update method, of class org.owasp.esapi.AccessReferenceMap. -

-

- -
Throws: -
AuthenticationException - the authentication exception -
java.lang.Exception
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/filters/SafeHTTPFilter.html b/javadoc/org/owasp/esapi/filters/SafeHTTPFilter.html deleted file mode 100644 index 3ba2d66b5..000000000 --- a/javadoc/org/owasp/esapi/filters/SafeHTTPFilter.html +++ /dev/null @@ -1,324 +0,0 @@ - - - - - - -SafeHTTPFilter - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.filters -
-Class SafeHTTPFilter

-
-java.lang.Object
-  extended byorg.owasp.esapi.filters.SafeHTTPFilter
-
-
-
All Implemented Interfaces:
javax.servlet.Filter
-
-
-
-
public class SafeHTTPFilter
extends java.lang.Object
implements javax.servlet.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. -

- -

-


- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
SafeHTTPFilter() - -
-           
-  - - - - - - - - - - - - - - - - - - - -
-Method Summary
- voiddestroy() - -
-           
- voiddoFilter(javax.servlet.ServletRequest request, - javax.servlet.ServletResponse response, - javax.servlet.FilterChain chain) - -
-           
- voidinit(javax.servlet.FilterConfig filterConfig) - -
-           
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-SafeHTTPFilter

-
-public SafeHTTPFilter()
-
-
- - - - - - - - -
-Method Detail
- -

-doFilter

-
-public void doFilter(javax.servlet.ServletRequest request,
-                     javax.servlet.ServletResponse response,
-                     javax.servlet.FilterChain chain)
-              throws java.io.IOException,
-                     javax.servlet.ServletException
-
-
-
Specified by:
doFilter in interface javax.servlet.Filter
-
-
- -
Throws: -
java.io.IOException -
javax.servlet.ServletException
-
-
-
- -

-destroy

-
-public void destroy()
-
-
-
Specified by:
destroy in interface javax.servlet.Filter
-
-
-
-
-
-
- -

-init

-
-public void init(javax.servlet.FilterConfig filterConfig)
-          throws javax.servlet.ServletException
-
-
-
Specified by:
init in interface javax.servlet.Filter
-
-
- -
Throws: -
javax.servlet.ServletException
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/filters/SafeHeaderFilter.html b/javadoc/org/owasp/esapi/filters/SafeHeaderFilter.html deleted file mode 100644 index bb9217a6f..000000000 --- a/javadoc/org/owasp/esapi/filters/SafeHeaderFilter.html +++ /dev/null @@ -1,323 +0,0 @@ - - - - - - -SafeHeaderFilter - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.filters -
-Class SafeHeaderFilter

-
-java.lang.Object
-  extended byorg.owasp.esapi.filters.SafeHeaderFilter
-
-
-
All Implemented Interfaces:
javax.servlet.Filter
-
-
-
-
public class SafeHeaderFilter
extends java.lang.Object
implements javax.servlet.Filter
- -

-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. -

- -

-


- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
SafeHeaderFilter() - -
-           
-  - - - - - - - - - - - - - - - - - - - -
-Method Summary
- voiddestroy() - -
-           
- voiddoFilter(javax.servlet.ServletRequest request, - javax.servlet.ServletResponse response, - javax.servlet.FilterChain chain) - -
-           
- voidinit(javax.servlet.FilterConfig filterConfig) - -
-           
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-SafeHeaderFilter

-
-public SafeHeaderFilter()
-
-
- - - - - - - - -
-Method Detail
- -

-doFilter

-
-public void doFilter(javax.servlet.ServletRequest request,
-                     javax.servlet.ServletResponse response,
-                     javax.servlet.FilterChain chain)
-              throws java.io.IOException,
-                     javax.servlet.ServletException
-
-
-
Specified by:
doFilter in interface javax.servlet.Filter
-
-
- -
Throws: -
java.io.IOException -
javax.servlet.ServletException
-
-
-
- -

-destroy

-
-public void destroy()
-
-
-
Specified by:
destroy in interface javax.servlet.Filter
-
-
-
-
-
-
- -

-init

-
-public void init(javax.servlet.FilterConfig filterConfig)
-          throws javax.servlet.ServletException
-
-
-
Specified by:
init in interface javax.servlet.Filter
-
-
- -
Throws: -
javax.servlet.ServletException
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/filters/SafeRequest.html b/javadoc/org/owasp/esapi/filters/SafeRequest.html deleted file mode 100644 index 71f68ab14..000000000 --- a/javadoc/org/owasp/esapi/filters/SafeRequest.html +++ /dev/null @@ -1,1614 +0,0 @@ - - - - - - -SafeRequest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.filters -
-Class SafeRequest

-
-java.lang.Object
-  extended byorg.owasp.esapi.filters.SafeRequest
-
-
-
All Implemented Interfaces:
javax.servlet.http.HttpServletRequest, javax.servlet.ServletRequest
-
-
-
-
public class SafeRequest
extends java.lang.Object
implements javax.servlet.http.HttpServletRequest
- -

-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
BASIC_AUTH, CLIENT_CERT_AUTH, DIGEST_AUTH, FORM_AUTH
-  - - - - - - - - - - -
-Constructor Summary
SafeRequest(javax.servlet.http.HttpServletRequest request) - -
-          Construct a safe request that overrides the default request methods with safer versions.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- java.lang.ObjectgetAttribute(java.lang.String name) - -
-          Same as HttpServletRequest, no security changes required.
- java.util.EnumerationgetAttributeNames() - -
-          Same as HttpServletRequest, no security changes required.
- java.lang.StringgetAuthType() - -
-          Same as HttpServletRequest, no security changes required.
- java.lang.StringgetCharacterEncoding() - -
-          Same as HttpServletRequest, no security changes required.
- intgetContentLength() - -
-          Same as HttpServletRequest, no security changes required.
- java.lang.StringgetContentType() - -
-          Same as HttpServletRequest, no security changes required.
- java.lang.StringgetContextPath() - -
-          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.
- longgetDateHeader(java.lang.String name) - -
-          Same as HttpServletRequest, no security changes required.
- java.lang.StringgetHeader(java.lang.String name) - -
-          Returns the named header from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters.
- java.util.EnumerationgetHeaderNames() - -
-          Returns the enumeration of header names from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters.
- java.util.EnumerationgetHeaders(java.lang.String name) - -
-          Returns the enumeration of headers from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters.
- javax.servlet.ServletInputStreamgetInputStream() - -
-          Same as HttpServletRequest, no security changes required.
- intgetIntHeader(java.lang.String name) - -
-          Same as HttpServletRequest, no security changes required.
- java.lang.StringgetLocalAddr() - -
-          Same as HttpServletRequest, no security changes required.
- java.util.LocalegetLocale() - -
-          Same as HttpServletRequest, no security changes required.
- java.util.EnumerationgetLocales() - -
-          Same as HttpServletRequest, no security changes required.
- java.lang.StringgetLocalName() - -
-          Same as HttpServletRequest, no security changes required.
- intgetLocalPort() - -
-          Same as HttpServletRequest, no security changes required.
- java.lang.StringgetMethod() - -
-          Same as HttpServletRequest, no security changes required.
- java.lang.StringgetParameter(java.lang.String name) - -
-          Returns the named parameter from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters.
- java.util.MapgetParameterMap() - -
-          Returns the parameter map from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters.
- java.util.EnumerationgetParameterNames() - -
-          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.StringgetPathInfo() - -
-          Returns the path info from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters.
- java.lang.StringgetPathTranslated() - -
-          Same as HttpServletRequest, no security changes required.
- java.lang.StringgetProtocol() - -
-          Same as HttpServletRequest, no security changes required.
- java.lang.StringgetQueryString() - -
-          Returns the query string from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters.
- java.io.BufferedReadergetReader() - -
-          Same as HttpServletRequest, no security changes required.
- java.lang.StringgetRealPath(java.lang.String path) - -
-          Same as HttpServletRequest, no security changes required.
- java.lang.StringgetRemoteAddr() - -
-          Same as HttpServletRequest, no security changes required.
- java.lang.StringgetRemoteHost() - -
-          Same as HttpServletRequest, no security changes required.
- intgetRemotePort() - -
-          Same as HttpServletRequest, no security changes required.
- java.lang.StringgetRemoteUser() - -
-          Returns the name of the ESAPI user associated with this request.
- javax.servlet.RequestDispatchergetRequestDispatcher(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.StringgetRequestedSessionId() - -
-          Returns the URI from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters.
- java.lang.StringgetRequestURI() - -
-          Returns the URI from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters.
- java.lang.StringBuffergetRequestURL() - -
-          Returns the URL from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters.
- java.lang.StringgetScheme() - -
-          Returns the scheme from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters.
- java.lang.StringgetServerName() - -
-          Returns the server name (host header) from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters.
- intgetServerPort() - -
-          Returns the server port (after the : in the host header) from the HttpServletRequest after - parsing and checking the range 0-65536.
- java.lang.StringgetServletPath() - -
-          Returns the server path from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters.
- javax.servlet.http.HttpSessiongetSession() - -
-          Returns a session, creating it if necessary, and sets the HttpOnly flag on the JSESSIONID cookie.
- javax.servlet.http.HttpSessiongetSession(boolean create) - -
-          Returns a session, creating it if necessary, and sets the HttpOnly flag on the JSESSIONID cookie.
- java.security.PrincipalgetUserPrincipal() - -
-          Returns the ESAPI User associated with this request.
- booleanisRequestedSessionIdFromCookie() - -
-          Same as HttpServletRequest, no security changes required.
- booleanisRequestedSessionIdFromUrl() - -
-          Same as HttpServletRequest, no security changes required.
- booleanisRequestedSessionIdFromURL() - -
-          Same as HttpServletRequest, no security changes required.
- booleanisRequestedSessionIdValid() - -
-          Same as HttpServletRequest, no security changes required.
- booleanisSecure() - -
-          Same as HttpServletRequest, no security changes required.
- booleanisUserInRole(java.lang.String role) - -
-          Returns true if the ESAPI User associated with this request has the specified role.
- voidremoveAttribute(java.lang.String name) - -
-          Same as HttpServletRequest, no security changes required.
- voidsetAttribute(java.lang.String name, - java.lang.Object o) - -
-          Same as HttpServletRequest, no security changes required.
- voidsetCharacterEncoding(java.lang.String enc) - -
-          Sets the character encoding to the ESAPI configured encoding.
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-SafeRequest

-
-public SafeRequest(javax.servlet.http.HttpServletRequest request)
-
-
Construct a safe request that overrides the default request methods with safer versions. -

-

Parameters:
request -
- - - - - - - - -
-Method Detail
- -

-getAttribute

-
-public java.lang.Object getAttribute(java.lang.String name)
-
-
Same as HttpServletRequest, no security changes required. -

-

-
Specified by:
getAttribute in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getAttributeNames

-
-public java.util.Enumeration getAttributeNames()
-
-
Same as HttpServletRequest, no security changes required. -

-

-
Specified by:
getAttributeNames in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getAuthType

-
-public java.lang.String getAuthType()
-
-
Same as HttpServletRequest, no security changes required. -

-

-
Specified by:
getAuthType in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getCharacterEncoding

-
-public java.lang.String getCharacterEncoding()
-
-
Same as HttpServletRequest, no security changes required. -

-

-
Specified by:
getCharacterEncoding in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getContentLength

-
-public int getContentLength()
-
-
Same as HttpServletRequest, no security changes required. -

-

-
Specified by:
getContentLength in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getContentType

-
-public java.lang.String getContentType()
-
-
Same as HttpServletRequest, no security changes required. -

-

-
Specified by:
getContentType in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getContextPath

-
-public java.lang.String getContextPath()
-
-
Returns the context path from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters. -

-

-
Specified by:
getContextPath in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getCookies

-
-public javax.servlet.http.Cookie[] getCookies()
-
-
Returns the array of Cookies from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters. -

-

-
Specified by:
getCookies in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getDateHeader

-
-public long getDateHeader(java.lang.String name)
-
-
Same as HttpServletRequest, no security changes required. -

-

-
Specified by:
getDateHeader in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getHeader

-
-public java.lang.String getHeader(java.lang.String name)
-
-
Returns the named header from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters. -

-

-
Specified by:
getHeader in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getHeaderNames

-
-public java.util.Enumeration getHeaderNames()
-
-
Returns the enumeration of header names from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters. -

-

-
Specified by:
getHeaderNames in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getHeaders

-
-public java.util.Enumeration getHeaders(java.lang.String name)
-
-
Returns the enumeration of headers from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters. -

-

-
Specified by:
getHeaders in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getInputStream

-
-public javax.servlet.ServletInputStream getInputStream()
-                                                throws java.io.IOException
-
-
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
-
-
-
-
-
-
- -

-getParameter

-
-public java.lang.String getParameter(java.lang.String name)
-
-
Returns the named parameter from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters. -

-

-
Specified by:
getParameter in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getParameterMap

-
-public java.util.Map getParameterMap()
-
-
Returns the parameter map from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters. -

-

-
Specified by:
getParameterMap in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getParameterNames

-
-public java.util.Enumeration getParameterNames()
-
-
Returns the enumeration of parameter names from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters. -

-

-
Specified by:
getParameterNames in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getParameterValues

-
-public 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. -

-

-
Specified by:
getParameterValues in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getPathInfo

-
-public java.lang.String getPathInfo()
-
-
Returns the path info from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters. -

-

-
Specified by:
getPathInfo in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getPathTranslated

-
-public java.lang.String getPathTranslated()
-
-
Same as HttpServletRequest, no security changes required. -

-

-
Specified by:
getPathTranslated in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getProtocol

-
-public java.lang.String getProtocol()
-
-
Same as HttpServletRequest, no security changes required. -

-

-
Specified by:
getProtocol in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getQueryString

-
-public java.lang.String getQueryString()
-
-
Returns the query string from the HttpServletRequest after - canonicalizing and filtering out any dangerous characters. -

-

-
Specified by:
getQueryString in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getReader

-
-public java.io.BufferedReader getReader()
-                                 throws java.io.IOException
-
-
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
-
-
- -
Throws: -
java.io.IOException
-
-
-
- -

-getRealPath

-
-public java.lang.String getRealPath(java.lang.String path)
-
-
Same as HttpServletRequest, no security changes required. -

-

-
Specified by:
getRealPath in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getRemoteAddr

-
-public java.lang.String getRemoteAddr()
-
-
Same as HttpServletRequest, no security changes required. -

-

-
Specified by:
getRemoteAddr in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getRemoteHost

-
-public java.lang.String getRemoteHost()
-
-
Same as HttpServletRequest, no security changes required. -

-

-
Specified by:
getRemoteHost in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getRemotePort

-
-public int getRemotePort()
-
-
Same as HttpServletRequest, no security changes required. -

-

-
Specified by:
getRemotePort in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getRemoteUser

-
-public java.lang.String getRemoteUser()
-
-
Returns the name of the ESAPI user associated with this request. -

-

-
Specified by:
getRemoteUser in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getRequestDispatcher

-
-public 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. 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
-
-
-
-
-
-
- -

-getSession

-
-public javax.servlet.http.HttpSession getSession()
-
-
Returns a session, creating it if necessary, and sets the HttpOnly flag on the JSESSIONID cookie. -

-

-
Specified by:
getSession in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getSession

-
-public javax.servlet.http.HttpSession getSession(boolean create)
-
-
Returns a session, creating it if necessary, and sets the HttpOnly flag on the JSESSIONID cookie. -

-

-
Specified by:
getSession in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getUserPrincipal

-
-public java.security.Principal getUserPrincipal()
-
-
Returns the ESAPI User associated with this request. -

-

-
Specified by:
getUserPrincipal in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-isRequestedSessionIdFromCookie

-
-public boolean isRequestedSessionIdFromCookie()
-
-
Same as HttpServletRequest, no security changes required. -

-

-
Specified by:
isRequestedSessionIdFromCookie in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-isRequestedSessionIdFromUrl

-
-public boolean isRequestedSessionIdFromUrl()
-
-
Same as HttpServletRequest, no security changes required. -

-

-
Specified by:
isRequestedSessionIdFromUrl in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-isRequestedSessionIdFromURL

-
-public boolean isRequestedSessionIdFromURL()
-
-
Same as HttpServletRequest, no security changes required. -

-

-
Specified by:
isRequestedSessionIdFromURL in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-isRequestedSessionIdValid

-
-public boolean isRequestedSessionIdValid()
-
-
Same as HttpServletRequest, no security changes required. -

-

-
Specified by:
isRequestedSessionIdValid in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-isSecure

-
-public boolean isSecure()
-
-
Same as HttpServletRequest, no security changes required. -

-

-
Specified by:
isSecure in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-isUserInRole

-
-public boolean isUserInRole(java.lang.String role)
-
-
Returns true if the ESAPI User associated with this request has the specified role. -

-

-
Specified by:
isUserInRole in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-removeAttribute

-
-public void removeAttribute(java.lang.String name)
-
-
Same as HttpServletRequest, no security changes required. -

-

-
Specified by:
removeAttribute in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-setAttribute

-
-public void setAttribute(java.lang.String name,
-                         java.lang.Object o)
-
-
Same as HttpServletRequest, no security changes required. -

-

-
Specified by:
setAttribute in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-setCharacterEncoding

-
-public void setCharacterEncoding(java.lang.String enc)
-                          throws java.io.UnsupportedEncodingException
-
-
Sets the character encoding to the ESAPI configured encoding. -

-

-
Specified by:
setCharacterEncoding in interface javax.servlet.ServletRequest
-
-
- -
Throws: -
java.io.UnsupportedEncodingException
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/filters/SafeResponse.html b/javadoc/org/owasp/esapi/filters/SafeResponse.html deleted file mode 100644 index b04c6b80c..000000000 --- a/javadoc/org/owasp/esapi/filters/SafeResponse.html +++ /dev/null @@ -1,1161 +0,0 @@ - - - - - - -SafeResponse - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.filters -
-Class SafeResponse

-
-java.lang.Object
-  extended byorg.owasp.esapi.filters.SafeResponse
-
-
-
All Implemented Interfaces:
javax.servlet.http.HttpServletResponse, javax.servlet.ServletResponse
-
-
-
-
public class SafeResponse
extends java.lang.Object
implements javax.servlet.http.HttpServletResponse
- -

-This response wrapper simply overrides unsafe methods in the - HttpServletResponse API with safe versions. -

- -

-


- -

- - - - - - - - - - -
-Field Summary
- - - - - - - -
Fields inherited from interface javax.servlet.http.HttpServletResponse
SC_ACCEPTED, SC_BAD_GATEWAY, SC_BAD_REQUEST, SC_CONFLICT, SC_CONTINUE, SC_CREATED, SC_EXPECTATION_FAILED, SC_FORBIDDEN, SC_FOUND, SC_GATEWAY_TIMEOUT, SC_GONE, SC_HTTP_VERSION_NOT_SUPPORTED, SC_INTERNAL_SERVER_ERROR, SC_LENGTH_REQUIRED, SC_METHOD_NOT_ALLOWED, SC_MOVED_PERMANENTLY, SC_MOVED_TEMPORARILY, SC_MULTIPLE_CHOICES, SC_NO_CONTENT, SC_NON_AUTHORITATIVE_INFORMATION, SC_NOT_ACCEPTABLE, SC_NOT_FOUND, SC_NOT_IMPLEMENTED, SC_NOT_MODIFIED, SC_OK, SC_PARTIAL_CONTENT, SC_PAYMENT_REQUIRED, SC_PRECONDITION_FAILED, SC_PROXY_AUTHENTICATION_REQUIRED, SC_REQUEST_ENTITY_TOO_LARGE, SC_REQUEST_TIMEOUT, SC_REQUEST_URI_TOO_LONG, SC_REQUESTED_RANGE_NOT_SATISFIABLE, SC_RESET_CONTENT, SC_SEE_OTHER, SC_SERVICE_UNAVAILABLE, SC_SWITCHING_PROTOCOLS, SC_TEMPORARY_REDIRECT, SC_UNAUTHORIZED, SC_UNSUPPORTED_MEDIA_TYPE, SC_USE_PROXY
-  - - - - - - - - - - -
-Constructor Summary
SafeResponse(javax.servlet.http.HttpServletResponse response) - -
-          Construct a safe response that overrides the default response methods - with safer versions.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- voidaddCookie(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.
- voidaddCookie(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.
- voidaddDateHeader(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.
- voidaddHeader(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.
- voidaddIntHeader(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.
- booleancontainsHeader(java.lang.String name) - -
-          Same as HttpServletResponse, no security changes required.
- java.lang.StringencodeRedirectUrl(java.lang.String url) - -
-          Return the URL without any changes, to prevent disclosure of the - JSESSIONID.
- java.lang.StringencodeRedirectURL(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.StringencodeUrl(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.StringencodeURL(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.
- voidflushBuffer() - -
-          Same as HttpServletResponse, no security changes required.
- intgetBufferSize() - -
-          Same as HttpServletResponse, no security changes required.
- java.lang.StringgetCharacterEncoding() - -
-          Same as HttpServletResponse, no security changes required.
- java.lang.StringgetContentType() - -
-          Same as HttpServletResponse, no security changes required.
- java.util.LocalegetLocale() - -
-          Same as HttpServletResponse, no security changes required.
- javax.servlet.ServletOutputStreamgetOutputStream() - -
-          Same as HttpServletResponse, no security changes required.
- java.io.PrintWritergetWriter() - -
-          Same as HttpServletResponse, no security changes required.
- booleanisCommitted() - -
-          Same as HttpServletResponse, no security changes required.
- voidreset() - -
-          Same as HttpServletResponse, no security changes required.
- voidresetBuffer() - -
-          Same as HttpServletResponse, no security changes required.
- voidsendError(int sc) - -
-          Override the error code with a 200 in order to confound attackers using - automated scanners.
- voidsendError(int sc, - java.lang.String msg) - -
-          Override the error code with a 200 in order to confound attackers using - automated scanners.
- voidsendRedirect(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.
- voidsetBufferSize(int size) - -
-          Same as HttpServletResponse, no security changes required.
- voidsetCharacterEncoding(java.lang.String charset) - -
-          Sets the character encoding to the ESAPI configured encoding.
- voidsetContentLength(int len) - -
-          Same as HttpServletResponse, no security changes required.
- voidsetContentType(java.lang.String type) - -
-          Same as HttpServletResponse, no security changes required.
- voidsetDateHeader(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.
- voidsetHeader(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.
- voidsetIntHeader(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.
- voidsetLocale(java.util.Locale loc) - -
-          Same as HttpServletResponse, no security changes required.
- voidsetStatus(int sc) - -
-          Override the status code with a 200 in order to confound attackers using - automated scanners.
- voidsetStatus(int sc, - java.lang.String sm) - -
-          Override the status code with a 200 in order to confound attackers using - automated scanners.
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-SafeResponse

-
-public SafeResponse(javax.servlet.http.HttpServletResponse response)
-
-
Construct a safe response that overrides the default response methods - with safer versions. -

-

Parameters:
response -
- - - - - - - - -
-Method Detail
- -

-addCookie

-
-public 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. This method also sets - the secure and HttpOnly flags on the cookie. -

-

-
Specified by:
addCookie in interface javax.servlet.http.HttpServletResponse
-
-
-
-
-
-
- -

-addCookie

-
-public 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. 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
-
-
-
-
-
-
- -

-addHeader

-
-public 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. 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
-
-
-
-
-
-
- -

-containsHeader

-
-public boolean containsHeader(java.lang.String name)
-
-
Same as HttpServletResponse, no security changes required. -

-

-
Specified by:
containsHeader in interface javax.servlet.http.HttpServletResponse
-
-
-
-
-
-
- -

-encodeRedirectUrl

-
-public 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. This - exposes the JSESSIONID credential in bookmarks, referer headers, server - logs, and more. -

-

-
Specified by:
encodeRedirectUrl in interface javax.servlet.http.HttpServletResponse
-
-
-
Parameters:
url - -
Returns:
original url
-
-
-
- -

-encodeRedirectURL

-
-public 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. This - exposes the JSESSIONID credential in bookmarks, referer headers, server - logs, and more. -

-

-
Specified by:
encodeRedirectURL in interface javax.servlet.http.HttpServletResponse
-
-
-
Parameters:
url - -
Returns:
original url
-
-
-
- -

-encodeUrl

-
-public 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. This - exposes the JSESSIONID credential in bookmarks, referer headers, server - logs, and more. -

-

-
Specified by:
encodeUrl in interface javax.servlet.http.HttpServletResponse
-
-
-
Parameters:
url - -
Returns:
original url
-
-
-
- -

-encodeURL

-
-public 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. This - exposes the JSESSIONID credential in bookmarks, referer headers, server - logs, and more. -

-

-
Specified by:
encodeURL in interface javax.servlet.http.HttpServletResponse
-
-
-
Parameters:
url - -
Returns:
original url
-
-
-
- -

-flushBuffer

-
-public void flushBuffer()
-                 throws java.io.IOException
-
-
Same as HttpServletResponse, no security changes required. -

-

-
Specified by:
flushBuffer in interface javax.servlet.ServletResponse
-
-
- -
Throws: -
java.io.IOException
-
-
-
- -

-getBufferSize

-
-public int getBufferSize()
-
-
Same as HttpServletResponse, no security changes required. -

-

-
Specified by:
getBufferSize in interface javax.servlet.ServletResponse
-
-
-
-
-
-
- -

-getCharacterEncoding

-
-public java.lang.String getCharacterEncoding()
-
-
Same as HttpServletResponse, no security changes required. -

-

-
Specified by:
getCharacterEncoding in interface javax.servlet.ServletResponse
-
-
-
-
-
-
- -

-getContentType

-
-public java.lang.String getContentType()
-
-
Same as HttpServletResponse, no security changes required. -

-

-
Specified by:
getContentType in interface javax.servlet.ServletResponse
-
-
-
-
-
-
- -

-getLocale

-
-public java.util.Locale getLocale()
-
-
Same as HttpServletResponse, no security changes required. -

-

-
Specified by:
getLocale in interface javax.servlet.ServletResponse
-
-
-
-
-
-
- -

-getOutputStream

-
-public javax.servlet.ServletOutputStream getOutputStream()
-                                                  throws java.io.IOException
-
-
Same as HttpServletResponse, no security changes required. -

-

-
Specified by:
getOutputStream in interface javax.servlet.ServletResponse
-
-
- -
Throws: -
java.io.IOException
-
-
-
- -

-getWriter

-
-public java.io.PrintWriter getWriter()
-                              throws java.io.IOException
-
-
Same as HttpServletResponse, no security changes required. -

-

-
Specified by:
getWriter in interface javax.servlet.ServletResponse
-
-
- -
Throws: -
java.io.IOException
-
-
-
- -

-isCommitted

-
-public boolean isCommitted()
-
-
Same as HttpServletResponse, no security changes required. -

-

-
Specified by:
isCommitted in interface javax.servlet.ServletResponse
-
-
-
-
-
-
- -

-reset

-
-public void reset()
-
-
Same as HttpServletResponse, no security changes required. -

-

-
Specified by:
reset in interface javax.servlet.ServletResponse
-
-
-
-
-
-
- -

-resetBuffer

-
-public void resetBuffer()
-
-
Same as HttpServletResponse, no security changes required. -

-

-
Specified by:
resetBuffer in interface javax.servlet.ServletResponse
-
-
-
-
-
-
- -

-sendError

-
-public void sendError(int sc)
-               throws java.io.IOException
-
-
Override the error code with a 200 in order to confound attackers using - automated scanners. -

-

-
Specified by:
sendError in interface javax.servlet.http.HttpServletResponse
-
-
- -
Throws: -
java.io.IOException
-
-
-
- -

-sendError

-
-public void sendError(int sc,
-                      java.lang.String msg)
-               throws java.io.IOException
-
-
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
-
-
- -
Throws: -
java.io.IOException
-
-
-
- -

-sendRedirect

-
-public void sendRedirect(java.lang.String location)
-                  throws java.io.IOException
-
-
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
-
-
-
-
-
-
- -

-setCharacterEncoding

-
-public void setCharacterEncoding(java.lang.String charset)
-
-
Sets the character encoding to the ESAPI configured encoding. -

-

-
Specified by:
setCharacterEncoding in interface javax.servlet.ServletResponse
-
-
-
-
-
-
- -

-setContentLength

-
-public void setContentLength(int len)
-
-
Same as HttpServletResponse, no security changes required. -

-

-
Specified by:
setContentLength in interface javax.servlet.ServletResponse
-
-
-
-
-
-
- -

-setContentType

-
-public void setContentType(java.lang.String type)
-
-
Same as HttpServletResponse, no security changes required. -

-

-
Specified by:
setContentType in interface javax.servlet.ServletResponse
-
-
-
-
-
-
- -

-setDateHeader

-
-public 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. -

-

-
Specified by:
setDateHeader in interface javax.servlet.http.HttpServletResponse
-
-
-
-
-
-
- -

-setHeader

-
-public 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. - "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
-
-
-
-
-
-
- -

-setStatus

-
-public void setStatus(int sc,
-                      java.lang.String sm)
-
-
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
-
-
-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/filters/class-use/ESAPIFilter.html b/javadoc/org/owasp/esapi/filters/class-use/ESAPIFilter.html deleted file mode 100644 index db368dd79..000000000 --- a/javadoc/org/owasp/esapi/filters/class-use/ESAPIFilter.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.filters.ESAPIFilter - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.filters.ESAPIFilter

-
-No usage of org.owasp.esapi.filters.ESAPIFilter -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/filters/class-use/ESAPIFilterTest.html b/javadoc/org/owasp/esapi/filters/class-use/ESAPIFilterTest.html deleted file mode 100644 index 929ce817b..000000000 --- a/javadoc/org/owasp/esapi/filters/class-use/ESAPIFilterTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.filters.ESAPIFilterTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.filters.ESAPIFilterTest

-
-No usage of org.owasp.esapi.filters.ESAPIFilterTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/filters/class-use/SafeHTTPFilter.html b/javadoc/org/owasp/esapi/filters/class-use/SafeHTTPFilter.html deleted file mode 100644 index 516544061..000000000 --- a/javadoc/org/owasp/esapi/filters/class-use/SafeHTTPFilter.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.filters.SafeHTTPFilter - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.filters.SafeHTTPFilter

-
-No usage of org.owasp.esapi.filters.SafeHTTPFilter -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/filters/class-use/SafeHeaderFilter.html b/javadoc/org/owasp/esapi/filters/class-use/SafeHeaderFilter.html deleted file mode 100644 index c0f981b6e..000000000 --- a/javadoc/org/owasp/esapi/filters/class-use/SafeHeaderFilter.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.filters.SafeHeaderFilter - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.filters.SafeHeaderFilter

-
-No usage of org.owasp.esapi.filters.SafeHeaderFilter -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/filters/class-use/SafeRequest.html b/javadoc/org/owasp/esapi/filters/class-use/SafeRequest.html deleted file mode 100644 index 791b54ec5..000000000 --- a/javadoc/org/owasp/esapi/filters/class-use/SafeRequest.html +++ /dev/null @@ -1,202 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.filters.SafeRequest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.filters.SafeRequest

-
- - - - - - - - - - - - - -
-Packages that use SafeRequest
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of SafeRequest in org.owasp.esapi
-  -

- - - - - - - - - -
Methods in org.owasp.esapi that return SafeRequest
- SafeRequestHTTPUtilities.getCurrentRequest() - -
-          Retrieves the current HttpServletRequest
-  -

- - - - - -
-Uses of SafeRequest in org.owasp.esapi.reference
-  -

- - - - - - - - - -
Methods in org.owasp.esapi.reference that return SafeRequest
- SafeRequestDefaultHTTPUtilities.getCurrentRequest() - -
-           
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/filters/class-use/SafeResponse.html b/javadoc/org/owasp/esapi/filters/class-use/SafeResponse.html deleted file mode 100644 index aa7042007..000000000 --- a/javadoc/org/owasp/esapi/filters/class-use/SafeResponse.html +++ /dev/null @@ -1,202 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.filters.SafeResponse - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.filters.SafeResponse

-
- - - - - - - - - - - - - -
-Packages that use SafeResponse
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of SafeResponse in org.owasp.esapi
-  -

- - - - - - - - - -
Methods in org.owasp.esapi that return SafeResponse
- SafeResponseHTTPUtilities.getCurrentResponse() - -
-          Retrieves the current HttpServletResponse
-  -

- - - - - -
-Uses of SafeResponse in org.owasp.esapi.reference
-  -

- - - - - - - - - -
Methods in org.owasp.esapi.reference that return SafeResponse
- SafeResponseDefaultHTTPUtilities.getCurrentResponse() - -
-           
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/filters/package-frame.html b/javadoc/org/owasp/esapi/filters/package-frame.html deleted file mode 100644 index 05124cec3..000000000 --- a/javadoc/org/owasp/esapi/filters/package-frame.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - -org.owasp.esapi.filters - - - - - - - - - - - -org.owasp.esapi.filters - - - - -
-Classes  - -
-ESAPIFilter -
-ESAPIFilterTest -
-SafeHTTPFilter -
-SafeRequest -
-SafeResponse
- - - - diff --git a/javadoc/org/owasp/esapi/filters/package-summary.html b/javadoc/org/owasp/esapi/filters/package-summary.html deleted file mode 100644 index 3045af641..000000000 --- a/javadoc/org/owasp/esapi/filters/package-summary.html +++ /dev/null @@ -1,167 +0,0 @@ - - - - - - -org.owasp.esapi.filters - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-

-Package org.owasp.esapi.filters -

- - - - - - - - - - - - - - - - - - - - - - - - - -
-Class Summary
ESAPIFilter 
ESAPIFilterTestThe Class AccessReferenceMapTest.
SafeHTTPFilterThis filter wraps the incoming request and outgoing response and overrides - many methods with safer versions.
SafeRequestThis request wrapper simply overrides unsafe methods in the HttpServletRequest - API with safe versions that return canonicalized data where possible.
SafeResponseThis response wrapper simply overrides unsafe methods in the - HttpServletResponse API with safe versions.
-  - -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/filters/package-tree.html b/javadoc/org/owasp/esapi/filters/package-tree.html deleted file mode 100644 index 1a784474e..000000000 --- a/javadoc/org/owasp/esapi/filters/package-tree.html +++ /dev/null @@ -1,154 +0,0 @@ - - - - - - -org.owasp.esapi.filters Class Hierarchy - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Hierarchy For Package org.owasp.esapi.filters -

-
-
-
Package Hierarchies:
All Packages
-
-

-Class Hierarchy -

-
    -
  • class java.lang.Object
      -
    • class junit.framework.Assert
        -
      • class junit.framework.TestCase (implements junit.framework.Test) - -
      -
    • class org.owasp.esapi.filters.ESAPIFilter (implements javax.servlet.Filter) -
    • class org.owasp.esapi.filters.SafeHTTPFilter (implements javax.servlet.Filter) -
    • class org.owasp.esapi.filters.SafeRequest (implements javax.servlet.http.HttpServletRequest) -
    • class org.owasp.esapi.filters.SafeResponse (implements javax.servlet.http.HttpServletResponse) -
    -
-
- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/filters/package-use.html b/javadoc/org/owasp/esapi/filters/package-use.html deleted file mode 100644 index bb5e6eb59..000000000 --- a/javadoc/org/owasp/esapi/filters/package-use.html +++ /dev/null @@ -1,198 +0,0 @@ - - - - - - -Uses of Package org.owasp.esapi.filters - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Package
org.owasp.esapi.filters

-
- - - - - - - - - - - - - -
-Packages that use org.owasp.esapi.filters
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - - - - - - - -
-Classes in org.owasp.esapi.filters used by org.owasp.esapi
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.
-  -

- - - - - - - - - - - -
-Classes in org.owasp.esapi.filters used by org.owasp.esapi.reference
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.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/http/TestFilterChain.html b/javadoc/org/owasp/esapi/http/TestFilterChain.html deleted file mode 100644 index 08d7f3421..000000000 --- a/javadoc/org/owasp/esapi/http/TestFilterChain.html +++ /dev/null @@ -1,265 +0,0 @@ - - - - - - -TestFilterChain - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.http -
-Class TestFilterChain

-
-java.lang.Object
-  extended byorg.owasp.esapi.http.TestFilterChain
-
-
-
All Implemented Interfaces:
javax.servlet.FilterChain
-
-
-
-
public class TestFilterChain
extends java.lang.Object
implements javax.servlet.FilterChain
- -

-


- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
TestFilterChain() - -
-           
-  - - - - - - - - - - - -
-Method Summary
- voiddoFilter(javax.servlet.ServletRequest request, - javax.servlet.ServletResponse response) - -
-           
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-TestFilterChain

-
-public TestFilterChain()
-
-
- - - - - - - - -
-Method Detail
- -

-doFilter

-
-public void doFilter(javax.servlet.ServletRequest request,
-                     javax.servlet.ServletResponse response)
-              throws java.io.IOException,
-                     javax.servlet.ServletException
-
-
-
Specified by:
doFilter in interface javax.servlet.FilterChain
-
-
- -
Throws: -
java.io.IOException -
javax.servlet.ServletException
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/http/TestHttpServletRequest.html b/javadoc/org/owasp/esapi/http/TestHttpServletRequest.html deleted file mode 100644 index f0550ca8a..000000000 --- a/javadoc/org/owasp/esapi/http/TestHttpServletRequest.html +++ /dev/null @@ -1,1688 +0,0 @@ - - - - - - -TestHttpServletRequest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.http -
-Class TestHttpServletRequest

-
-java.lang.Object
-  extended byorg.owasp.esapi.http.TestHttpServletRequest
-
-
-
All Implemented Interfaces:
javax.servlet.http.HttpServletRequest, javax.servlet.ServletRequest
-
-
-
-
public class TestHttpServletRequest
extends java.lang.Object
implements javax.servlet.http.HttpServletRequest
- -

-The Class TestHttpServletRequest. -

- -

-

-
Author:
-
jwilliams
-
-
- -

- - - - - - - - - - -
-Field Summary
- - - - - - - -
Fields inherited from interface javax.servlet.http.HttpServletRequest
BASIC_AUTH, CLIENT_CERT_AUTH, DIGEST_AUTH, FORM_AUTH
-  - - - - - - - - - - - - - -
-Constructor Summary
TestHttpServletRequest() - -
-           
TestHttpServletRequest(java.lang.String uri, - byte[] body) - -
-           
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- voidaddHeader(java.lang.String name, - java.lang.String value) - -
-          Adds the header.
- voidaddParameter(java.lang.String name, - java.lang.String value) - -
-          Adds the parameter.
- voidclearCookies() - -
-           
- java.lang.ObjectgetAttribute(java.lang.String name) - -
-           
- java.util.EnumerationgetAttributeNames() - -
-           
- java.lang.StringgetAuthType() - -
-           
- java.lang.StringgetCharacterEncoding() - -
-           
- intgetContentLength() - -
-           
- java.lang.StringgetContentType() - -
-           
- java.lang.StringgetContextPath() - -
-           
- javax.servlet.http.Cookie[]getCookies() - -
-           
- longgetDateHeader(java.lang.String name) - -
-           
- java.lang.StringgetHeader(java.lang.String name) - -
-           
- java.util.EnumerationgetHeaderNames() - -
-           
- java.util.EnumerationgetHeaders(java.lang.String name) - -
-           
- javax.servlet.ServletInputStreamgetInputStream() - -
-           
- intgetIntHeader(java.lang.String name) - -
-           
- java.lang.StringgetLocalAddr() - -
-           
- java.util.LocalegetLocale() - -
-           
- java.util.EnumerationgetLocales() - -
-           
- java.lang.StringgetLocalName() - -
-           
- intgetLocalPort() - -
-           
- java.lang.StringgetMethod() - -
-           
- java.lang.StringgetParameter(java.lang.String name) - -
-           
- java.util.MapgetParameterMap() - -
-           
- java.util.EnumerationgetParameterNames() - -
-           
- java.lang.String[]getParameterValues(java.lang.String name) - -
-           
- java.lang.StringgetPathInfo() - -
-           
- java.lang.StringgetPathTranslated() - -
-           
- java.lang.StringgetProtocol() - -
-           
- java.lang.StringgetQueryString() - -
-           
- java.io.BufferedReadergetReader() - -
-           
- java.lang.StringgetRealPath(java.lang.String path) - -
-           
- java.lang.StringgetRemoteAddr() - -
-           
- java.lang.StringgetRemoteHost() - -
-           
- intgetRemotePort() - -
-           
- java.lang.StringgetRemoteUser() - -
-           
- javax.servlet.RequestDispatchergetRequestDispatcher(java.lang.String path) - -
-           
- java.lang.StringgetRequestedSessionId() - -
-           
- java.lang.StringgetRequestURI() - -
-           
- java.lang.StringBuffergetRequestURL() - -
-           
- java.lang.StringgetScheme() - -
-           
- java.lang.StringgetServerName() - -
-           
- intgetServerPort() - -
-           
- java.lang.StringgetServletPath() - -
-           
- javax.servlet.http.HttpSessiongetSession() - -
-           
- javax.servlet.http.HttpSessiongetSession(boolean create) - -
-           
- java.security.PrincipalgetUserPrincipal() - -
-           
- booleanisRequestedSessionIdFromCookie() - -
-           
- booleanisRequestedSessionIdFromUrl() - -
-           
- booleanisRequestedSessionIdFromURL() - -
-           
- booleanisRequestedSessionIdValid() - -
-           
- booleanisSecure() - -
-           
- booleanisUserInRole(java.lang.String role) - -
-           
- voidremoveAttribute(java.lang.String name) - -
-           
- voidremoveParameter(java.lang.String name) - -
-           
- voidsetAttribute(java.lang.String name, - java.lang.Object o) - -
-           
- voidsetCharacterEncoding(java.lang.String env) - -
-           
- voidsetContentType(java.lang.String value) - -
-           
- voidsetCookie(java.lang.String name, - java.lang.String value) - -
-           
- voidsetCookies(java.util.ArrayList list) - -
-          Sets the cookies.
- voidsetMethod(java.lang.String value) - -
-           
- voidsetRequestURI(java.lang.String uri) - -
-           
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-TestHttpServletRequest

-
-public TestHttpServletRequest()
-
-
-
- -

-TestHttpServletRequest

-
-public TestHttpServletRequest(java.lang.String uri,
-                              byte[] body)
-
-
- - - - - - - - -
-Method Detail
- -

-getAuthType

-
-public java.lang.String getAuthType()
-
-
-
Specified by:
getAuthType in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getContextPath

-
-public java.lang.String getContextPath()
-
-
-
Specified by:
getContextPath in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-addParameter

-
-public void addParameter(java.lang.String name,
-                         java.lang.String value)
-
-
Adds the parameter. -

-

-
-
-
-
Parameters:
name - the name
value - the value
-
-
-
- -

-removeParameter

-
-public void removeParameter(java.lang.String name)
-
-
-
-
-
-
-
-
-
- -

-addHeader

-
-public void addHeader(java.lang.String name,
-                      java.lang.String value)
-
-
Adds the header. -

-

-
-
-
-
Parameters:
name - the name
value - the value
-
-
-
- -

-setCookies

-
-public void setCookies(java.util.ArrayList list)
-
-
Sets the cookies. -

-

-
-
-
-
Parameters:
list - the new cookies
-
-
-
- -

-setCookie

-
-public void setCookie(java.lang.String name,
-                      java.lang.String value)
-
-
-
-
-
-
-
-
-
- -

-clearCookies

-
-public void clearCookies()
-
-
-
-
-
-
-
-
-
- -

-getCookies

-
-public javax.servlet.http.Cookie[] getCookies()
-
-
-
Specified by:
getCookies in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getDateHeader

-
-public long getDateHeader(java.lang.String name)
-
-
-
Specified by:
getDateHeader in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getHeader

-
-public java.lang.String getHeader(java.lang.String name)
-
-
-
Specified by:
getHeader in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getHeaderNames

-
-public java.util.Enumeration getHeaderNames()
-
-
-
Specified by:
getHeaderNames in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getHeaders

-
-public java.util.Enumeration getHeaders(java.lang.String name)
-
-
-
Specified by:
getHeaders in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getIntHeader

-
-public int getIntHeader(java.lang.String name)
-
-
-
Specified by:
getIntHeader in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getMethod

-
-public java.lang.String getMethod()
-
-
-
Specified by:
getMethod in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-setMethod

-
-public void setMethod(java.lang.String value)
-
-
-
-
-
-
-
-
-
- -

-getPathInfo

-
-public java.lang.String getPathInfo()
-
-
-
Specified by:
getPathInfo in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getPathTranslated

-
-public java.lang.String getPathTranslated()
-
-
-
Specified by:
getPathTranslated in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getQueryString

-
-public java.lang.String getQueryString()
-
-
-
Specified by:
getQueryString in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getRemoteUser

-
-public java.lang.String getRemoteUser()
-
-
-
Specified by:
getRemoteUser in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getRequestURI

-
-public java.lang.String getRequestURI()
-
-
-
Specified by:
getRequestURI in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getRequestURL

-
-public java.lang.StringBuffer getRequestURL()
-
-
-
Specified by:
getRequestURL in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getRequestedSessionId

-
-public java.lang.String getRequestedSessionId()
-
-
-
Specified by:
getRequestedSessionId in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getServletPath

-
-public java.lang.String getServletPath()
-
-
-
Specified by:
getServletPath in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getSession

-
-public javax.servlet.http.HttpSession getSession()
-
-
-
Specified by:
getSession in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getSession

-
-public javax.servlet.http.HttpSession getSession(boolean create)
-
-
-
Specified by:
getSession in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getUserPrincipal

-
-public java.security.Principal getUserPrincipal()
-
-
-
Specified by:
getUserPrincipal in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-isRequestedSessionIdFromCookie

-
-public boolean isRequestedSessionIdFromCookie()
-
-
-
Specified by:
isRequestedSessionIdFromCookie in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-isRequestedSessionIdFromURL

-
-public boolean isRequestedSessionIdFromURL()
-
-
-
Specified by:
isRequestedSessionIdFromURL in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-isRequestedSessionIdFromUrl

-
-public boolean isRequestedSessionIdFromUrl()
-
-
-
Specified by:
isRequestedSessionIdFromUrl in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-isRequestedSessionIdValid

-
-public boolean isRequestedSessionIdValid()
-
-
-
Specified by:
isRequestedSessionIdValid in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-isUserInRole

-
-public boolean isUserInRole(java.lang.String role)
-
-
-
Specified by:
isUserInRole in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
- -

-getAttribute

-
-public java.lang.Object getAttribute(java.lang.String name)
-
-
-
Specified by:
getAttribute in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getAttributeNames

-
-public java.util.Enumeration getAttributeNames()
-
-
-
Specified by:
getAttributeNames in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getCharacterEncoding

-
-public java.lang.String getCharacterEncoding()
-
-
-
Specified by:
getCharacterEncoding in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getContentLength

-
-public int getContentLength()
-
-
-
Specified by:
getContentLength in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getContentType

-
-public java.lang.String getContentType()
-
-
-
Specified by:
getContentType in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-setContentType

-
-public void setContentType(java.lang.String value)
-
-
-
-
-
-
-
-
-
- -

-getInputStream

-
-public javax.servlet.ServletInputStream getInputStream()
-                                                throws java.io.IOException
-
-
-
Specified by:
getInputStream in interface javax.servlet.ServletRequest
-
-
- -
Throws: -
java.io.IOException
-
-
-
- -

-getLocalAddr

-
-public java.lang.String getLocalAddr()
-
-
-
Specified by:
getLocalAddr in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getLocalName

-
-public java.lang.String getLocalName()
-
-
-
Specified by:
getLocalName in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getLocalPort

-
-public int getLocalPort()
-
-
-
Specified by:
getLocalPort in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getLocale

-
-public java.util.Locale getLocale()
-
-
-
Specified by:
getLocale in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getLocales

-
-public java.util.Enumeration getLocales()
-
-
-
Specified by:
getLocales in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getParameter

-
-public java.lang.String getParameter(java.lang.String name)
-
-
-
Specified by:
getParameter in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getParameterMap

-
-public java.util.Map getParameterMap()
-
-
-
Specified by:
getParameterMap in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getParameterNames

-
-public java.util.Enumeration getParameterNames()
-
-
-
Specified by:
getParameterNames in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getParameterValues

-
-public java.lang.String[] getParameterValues(java.lang.String name)
-
-
-
Specified by:
getParameterValues in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getProtocol

-
-public java.lang.String getProtocol()
-
-
-
Specified by:
getProtocol in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getReader

-
-public java.io.BufferedReader getReader()
-                                 throws java.io.IOException
-
-
-
Specified by:
getReader in interface javax.servlet.ServletRequest
-
-
- -
Throws: -
java.io.IOException
-
-
-
- -

-getRealPath

-
-public java.lang.String getRealPath(java.lang.String path)
-
-
-
Specified by:
getRealPath in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getRemoteAddr

-
-public java.lang.String getRemoteAddr()
-
-
-
Specified by:
getRemoteAddr in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getRemoteHost

-
-public java.lang.String getRemoteHost()
-
-
-
Specified by:
getRemoteHost in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getRemotePort

-
-public int getRemotePort()
-
-
-
Specified by:
getRemotePort in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getRequestDispatcher

-
-public javax.servlet.RequestDispatcher getRequestDispatcher(java.lang.String path)
-
-
-
Specified by:
getRequestDispatcher in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getScheme

-
-public java.lang.String getScheme()
-
-
-
Specified by:
getScheme in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getServerName

-
-public java.lang.String getServerName()
-
-
-
Specified by:
getServerName in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-getServerPort

-
-public int getServerPort()
-
-
-
Specified by:
getServerPort in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-isSecure

-
-public boolean isSecure()
-
-
-
Specified by:
isSecure in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-removeAttribute

-
-public void removeAttribute(java.lang.String name)
-
-
-
Specified by:
removeAttribute in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-setAttribute

-
-public void setAttribute(java.lang.String name,
-                         java.lang.Object o)
-
-
-
Specified by:
setAttribute in interface javax.servlet.ServletRequest
-
-
-
-
-
-
- -

-setCharacterEncoding

-
-public void setCharacterEncoding(java.lang.String env)
-                          throws java.io.UnsupportedEncodingException
-
-
-
Specified by:
setCharacterEncoding in interface javax.servlet.ServletRequest
-
-
- -
Throws: -
java.io.UnsupportedEncodingException
-
-
-
- -

-setRequestURI

-
-public void setRequestURI(java.lang.String uri)
-                   throws java.io.UnsupportedEncodingException
-
-
-
-
-
- -
Throws: -
java.io.UnsupportedEncodingException
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/http/TestHttpServletResponse.html b/javadoc/org/owasp/esapi/http/TestHttpServletResponse.html deleted file mode 100644 index d13c21225..000000000 --- a/javadoc/org/owasp/esapi/http/TestHttpServletResponse.html +++ /dev/null @@ -1,1120 +0,0 @@ - - - - - - -TestHttpServletResponse - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.http -
-Class TestHttpServletResponse

-
-java.lang.Object
-  extended byorg.owasp.esapi.http.TestHttpServletResponse
-
-
-
All Implemented Interfaces:
javax.servlet.http.HttpServletResponse, javax.servlet.ServletResponse
-
-
-
-
public class TestHttpServletResponse
extends java.lang.Object
implements javax.servlet.http.HttpServletResponse
- -

-The Class TestHttpServletResponse. -

- -

-

-
Author:
-
jwilliams
-
-
- -

- - - - - - - - - - -
-Field Summary
- - - - - - - -
Fields inherited from interface javax.servlet.http.HttpServletResponse
SC_ACCEPTED, SC_BAD_GATEWAY, SC_BAD_REQUEST, SC_CONFLICT, SC_CONTINUE, SC_CREATED, SC_EXPECTATION_FAILED, SC_FORBIDDEN, SC_FOUND, SC_GATEWAY_TIMEOUT, SC_GONE, SC_HTTP_VERSION_NOT_SUPPORTED, SC_INTERNAL_SERVER_ERROR, SC_LENGTH_REQUIRED, SC_METHOD_NOT_ALLOWED, SC_MOVED_PERMANENTLY, SC_MOVED_TEMPORARILY, SC_MULTIPLE_CHOICES, SC_NO_CONTENT, SC_NON_AUTHORITATIVE_INFORMATION, SC_NOT_ACCEPTABLE, SC_NOT_FOUND, SC_NOT_IMPLEMENTED, SC_NOT_MODIFIED, SC_OK, SC_PARTIAL_CONTENT, SC_PAYMENT_REQUIRED, SC_PRECONDITION_FAILED, SC_PROXY_AUTHENTICATION_REQUIRED, SC_REQUEST_ENTITY_TOO_LARGE, SC_REQUEST_TIMEOUT, SC_REQUEST_URI_TOO_LONG, SC_REQUESTED_RANGE_NOT_SATISFIABLE, SC_RESET_CONTENT, SC_SEE_OTHER, SC_SERVICE_UNAVAILABLE, SC_SWITCHING_PROTOCOLS, SC_TEMPORARY_REDIRECT, SC_UNAUTHORIZED, SC_UNSUPPORTED_MEDIA_TYPE, SC_USE_PROXY
-  - - - - - - - - - - -
-Constructor Summary
TestHttpServletResponse() - -
-           
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- voidaddCookie(javax.servlet.http.Cookie cookie) - -
-           
- voidaddDateHeader(java.lang.String name, - long date) - -
-           
- voidaddHeader(java.lang.String name, - java.lang.String value) - -
-           
- voidaddIntHeader(java.lang.String name, - int value) - -
-           
- booleancontainsHeader(java.lang.String name) - -
-           
- java.lang.StringencodeRedirectUrl(java.lang.String url) - -
-           
- java.lang.StringencodeRedirectURL(java.lang.String url) - -
-           
- java.lang.StringencodeUrl(java.lang.String url) - -
-           
- java.lang.StringencodeURL(java.lang.String url) - -
-           
- voidflushBuffer() - -
-           
- intgetBufferSize() - -
-           
- java.lang.StringgetCharacterEncoding() - -
-           
- java.lang.StringgetContentType() - -
-           
- javax.servlet.http.CookiegetCookie(java.lang.String name) - -
-           
- java.util.ListgetCookies() - -
-          Gets the cookies.
- java.lang.StringgetHeader(java.lang.String name) - -
-          Gets the header.
- java.util.ListgetHeaderNames() - -
-          Gets the header names.
- java.util.LocalegetLocale() - -
-           
- javax.servlet.ServletOutputStreamgetOutputStream() - -
-           
- intgetStatus() - -
-          Gets the status.
- java.io.PrintWritergetWriter() - -
-           
- booleanisCommitted() - -
-           
- voidreset() - -
-           
- voidresetBuffer() - -
-           
- voidsendError(int sc) - -
-           
- voidsendError(int sc, - java.lang.String msg) - -
-           
- voidsendRedirect(java.lang.String location) - -
-           
- voidsetBufferSize(int size) - -
-           
- voidsetCharacterEncoding(java.lang.String charset) - -
-           
- voidsetContentLength(int len) - -
-           
- voidsetContentType(java.lang.String type) - -
-           
- voidsetDateHeader(java.lang.String name, - long date) - -
-           
- voidsetHeader(java.lang.String name, - java.lang.String value) - -
-           
- voidsetIntHeader(java.lang.String name, - int value) - -
-           
- voidsetLocale(java.util.Locale loc) - -
-           
- voidsetStatus(int sc) - -
-           
- voidsetStatus(int sc, - java.lang.String sm) - -
-           
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-TestHttpServletResponse

-
-public TestHttpServletResponse()
-
-
- - - - - - - - -
-Method Detail
- -

-addCookie

-
-public void addCookie(javax.servlet.http.Cookie cookie)
-
-
-
Specified by:
addCookie in interface javax.servlet.http.HttpServletResponse
-
-
-
-
-
-
- -

-getCookies

-
-public java.util.List getCookies()
-
-
Gets the cookies. -

-

-
-
-
- -
Returns:
the cookies
-
-
-
- -

-getCookie

-
-public javax.servlet.http.Cookie getCookie(java.lang.String name)
-
-
-
-
-
-
-
-
-
- -

-addDateHeader

-
-public void addDateHeader(java.lang.String name,
-                          long date)
-
-
-
Specified by:
addDateHeader in interface javax.servlet.http.HttpServletResponse
-
-
-
-
-
-
- -

-addHeader

-
-public void addHeader(java.lang.String name,
-                      java.lang.String value)
-
-
-
Specified by:
addHeader in interface javax.servlet.http.HttpServletResponse
-
-
-
-
-
-
- -

-addIntHeader

-
-public void addIntHeader(java.lang.String name,
-                         int value)
-
-
-
Specified by:
addIntHeader in interface javax.servlet.http.HttpServletResponse
-
-
-
-
-
-
- -

-containsHeader

-
-public boolean containsHeader(java.lang.String name)
-
-
-
Specified by:
containsHeader in interface javax.servlet.http.HttpServletResponse
-
-
-
-
-
-
- -

-getHeader

-
-public java.lang.String getHeader(java.lang.String name)
-
-
Gets the header. -

-

-
-
-
-
Parameters:
name - the name -
Returns:
the header
-
-
-
- -

-getHeaderNames

-
-public java.util.List getHeaderNames()
-
-
Gets the header names. -

-

-
-
-
- -
Returns:
the header names
-
-
-
- -

-encodeRedirectURL

-
-public java.lang.String encodeRedirectURL(java.lang.String url)
-
-
-
Specified by:
encodeRedirectURL in interface javax.servlet.http.HttpServletResponse
-
-
-
-
-
-
- -

-encodeRedirectUrl

-
-public java.lang.String encodeRedirectUrl(java.lang.String url)
-
-
-
Specified by:
encodeRedirectUrl in interface javax.servlet.http.HttpServletResponse
-
-
-
-
-
-
- -

-encodeURL

-
-public java.lang.String encodeURL(java.lang.String url)
-
-
-
Specified by:
encodeURL in interface javax.servlet.http.HttpServletResponse
-
-
-
-
-
-
- -

-encodeUrl

-
-public java.lang.String encodeUrl(java.lang.String url)
-
-
-
Specified by:
encodeUrl in interface javax.servlet.http.HttpServletResponse
-
-
-
-
-
-
- -

-sendError

-
-public void sendError(int sc)
-               throws java.io.IOException
-
-
-
Specified by:
sendError in interface javax.servlet.http.HttpServletResponse
-
-
- -
Throws: -
java.io.IOException
-
-
-
- -

-sendError

-
-public void sendError(int sc,
-                      java.lang.String msg)
-               throws java.io.IOException
-
-
-
Specified by:
sendError in interface javax.servlet.http.HttpServletResponse
-
-
- -
Throws: -
java.io.IOException
-
-
-
- -

-sendRedirect

-
-public void sendRedirect(java.lang.String location)
-                  throws java.io.IOException
-
-
-
Specified by:
sendRedirect in interface javax.servlet.http.HttpServletResponse
-
-
- -
Throws: -
java.io.IOException
-
-
-
- -

-setDateHeader

-
-public void setDateHeader(java.lang.String name,
-                          long date)
-
-
-
Specified by:
setDateHeader in interface javax.servlet.http.HttpServletResponse
-
-
-
-
-
-
- -

-setHeader

-
-public void setHeader(java.lang.String name,
-                      java.lang.String value)
-
-
-
Specified by:
setHeader in interface javax.servlet.http.HttpServletResponse
-
-
-
-
-
-
- -

-setIntHeader

-
-public void setIntHeader(java.lang.String name,
-                         int value)
-
-
-
Specified by:
setIntHeader in interface javax.servlet.http.HttpServletResponse
-
-
-
-
-
-
- -

-setStatus

-
-public void setStatus(int sc)
-
-
-
Specified by:
setStatus in interface javax.servlet.http.HttpServletResponse
-
-
-
-
-
-
- -

-getStatus

-
-public int getStatus()
-
-
Gets the status. -

-

-
-
-
- -
Returns:
the status
-
-
-
- -

-setStatus

-
-public void setStatus(int sc,
-                      java.lang.String sm)
-
-
-
Specified by:
setStatus in interface javax.servlet.http.HttpServletResponse
-
-
-
-
-
-
- -

-flushBuffer

-
-public void flushBuffer()
-                 throws java.io.IOException
-
-
-
Specified by:
flushBuffer in interface javax.servlet.ServletResponse
-
-
- -
Throws: -
java.io.IOException
-
-
-
- -

-getBufferSize

-
-public int getBufferSize()
-
-
-
Specified by:
getBufferSize in interface javax.servlet.ServletResponse
-
-
-
-
-
-
- -

-getCharacterEncoding

-
-public java.lang.String getCharacterEncoding()
-
-
-
Specified by:
getCharacterEncoding in interface javax.servlet.ServletResponse
-
-
-
-
-
-
- -

-getContentType

-
-public java.lang.String getContentType()
-
-
-
Specified by:
getContentType in interface javax.servlet.ServletResponse
-
-
-
-
-
-
- -

-getLocale

-
-public java.util.Locale getLocale()
-
-
-
Specified by:
getLocale in interface javax.servlet.ServletResponse
-
-
-
-
-
-
- -

-getOutputStream

-
-public javax.servlet.ServletOutputStream getOutputStream()
-                                                  throws java.io.IOException
-
-
-
Specified by:
getOutputStream in interface javax.servlet.ServletResponse
-
-
- -
Throws: -
java.io.IOException
-
-
-
- -

-getWriter

-
-public java.io.PrintWriter getWriter()
-                              throws java.io.IOException
-
-
-
Specified by:
getWriter in interface javax.servlet.ServletResponse
-
-
- -
Throws: -
java.io.IOException
-
-
-
- -

-isCommitted

-
-public boolean isCommitted()
-
-
-
Specified by:
isCommitted in interface javax.servlet.ServletResponse
-
-
-
-
-
-
- -

-reset

-
-public void reset()
-
-
-
Specified by:
reset in interface javax.servlet.ServletResponse
-
-
-
-
-
-
- -

-resetBuffer

-
-public void resetBuffer()
-
-
-
Specified by:
resetBuffer in interface javax.servlet.ServletResponse
-
-
-
-
-
-
- -

-setBufferSize

-
-public void setBufferSize(int size)
-
-
-
Specified by:
setBufferSize in interface javax.servlet.ServletResponse
-
-
-
-
-
-
- -

-setCharacterEncoding

-
-public void setCharacterEncoding(java.lang.String charset)
-
-
-
Specified by:
setCharacterEncoding in interface javax.servlet.ServletResponse
-
-
-
-
-
-
- -

-setContentLength

-
-public void setContentLength(int len)
-
-
-
Specified by:
setContentLength in interface javax.servlet.ServletResponse
-
-
-
-
-
-
- -

-setContentType

-
-public void setContentType(java.lang.String type)
-
-
-
Specified by:
setContentType in interface javax.servlet.ServletResponse
-
-
-
-
-
-
- -

-setLocale

-
-public void setLocale(java.util.Locale loc)
-
-
-
Specified by:
setLocale in interface javax.servlet.ServletResponse
-
-
-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/http/TestHttpSession.html b/javadoc/org/owasp/esapi/http/TestHttpSession.html deleted file mode 100644 index 4bef523a6..000000000 --- a/javadoc/org/owasp/esapi/http/TestHttpSession.html +++ /dev/null @@ -1,711 +0,0 @@ - - - - - - -TestHttpSession - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.http -
-Class TestHttpSession

-
-java.lang.Object
-  extended byorg.owasp.esapi.http.TestHttpSession
-
-
-
All Implemented Interfaces:
javax.servlet.http.HttpSession
-
-
-
-
public class TestHttpSession
extends java.lang.Object
implements javax.servlet.http.HttpSession
- -

-The Class TestHttpSession. -

- -

-

-
Author:
-
jwilliams
-
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
TestHttpSession() - -
-          Instantiates a new test http session.
TestHttpSession(long creationTime, - long accessedTime) - -
-          Instantiates a new test http session.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- java.lang.ObjectgetAttribute(java.lang.String string) - -
-           
- java.util.EnumerationgetAttributeNames() - -
-           
- longgetCreationTime() - -
-           
- java.lang.StringgetId() - -
-           
- booleangetInvalidated() - -
-          Gets the invalidated.
- longgetLastAccessedTime() - -
-           
- intgetMaxInactiveInterval() - -
-           
- javax.servlet.ServletContextgetServletContext() - -
-           
- javax.servlet.http.HttpSessionContextgetSessionContext() - -
-           
- java.lang.ObjectgetValue(java.lang.String string) - -
-           
- java.lang.String[]getValueNames() - -
-           
- voidinvalidate() - -
-           
- booleanisNew() - -
-           
- voidputValue(java.lang.String string, - java.lang.Object object) - -
-           
- voidremoveAttribute(java.lang.String string) - -
-           
- voidremoveValue(java.lang.String string) - -
-           
- voidsetAccessedTime(long time) - -
-           
- voidsetAttribute(java.lang.String string, - java.lang.Object object) - -
-           
- voidsetCreationTime(long time) - -
-           
- voidsetMaxInactiveInterval(int i) - -
-           
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-TestHttpSession

-
-public TestHttpSession()
-
-
Instantiates a new test http session. -

-

-
- -

-TestHttpSession

-
-public TestHttpSession(long creationTime,
-                       long accessedTime)
-
-
Instantiates a new test http session. -

-

Parameters:
creationTime - the creation time
accessedTime - the accessed time
- - - - - - - - -
-Method Detail
- -

-getAttribute

-
-public java.lang.Object getAttribute(java.lang.String string)
-
-
-
Specified by:
getAttribute in interface javax.servlet.http.HttpSession
-
-
-
-
-
-
- -

-getAttributeNames

-
-public java.util.Enumeration getAttributeNames()
-
-
-
Specified by:
getAttributeNames in interface javax.servlet.http.HttpSession
-
-
-
-
-
-
- -

-getCreationTime

-
-public long getCreationTime()
-
-
-
Specified by:
getCreationTime in interface javax.servlet.http.HttpSession
-
-
-
-
-
-
- -

-getId

-
-public java.lang.String getId()
-
-
-
Specified by:
getId in interface javax.servlet.http.HttpSession
-
-
-
-
-
-
- -

-getInvalidated

-
-public boolean getInvalidated()
-
-
Gets the invalidated. -

-

-
-
-
- -
Returns:
the invalidated
-
-
-
- -

-getLastAccessedTime

-
-public long getLastAccessedTime()
-
-
-
Specified by:
getLastAccessedTime in interface javax.servlet.http.HttpSession
-
-
-
-
-
-
- -

-getMaxInactiveInterval

-
-public int getMaxInactiveInterval()
-
-
-
Specified by:
getMaxInactiveInterval in interface javax.servlet.http.HttpSession
-
-
-
-
-
-
- -

-getServletContext

-
-public javax.servlet.ServletContext getServletContext()
-
-
-
Specified by:
getServletContext in interface javax.servlet.http.HttpSession
-
-
-
-
-
-
- -

-getSessionContext

-
-public javax.servlet.http.HttpSessionContext getSessionContext()
-
-
-
Specified by:
getSessionContext in interface javax.servlet.http.HttpSession
-
-
-
-
-
-
- -

-getValue

-
-public java.lang.Object getValue(java.lang.String string)
-
-
-
Specified by:
getValue in interface javax.servlet.http.HttpSession
-
-
-
-
-
-
- -

-getValueNames

-
-public java.lang.String[] getValueNames()
-
-
-
Specified by:
getValueNames in interface javax.servlet.http.HttpSession
-
-
-
-
-
-
- -

-invalidate

-
-public void invalidate()
-
-
-
Specified by:
invalidate in interface javax.servlet.http.HttpSession
-
-
-
-
-
-
- -

-isNew

-
-public boolean isNew()
-
-
-
Specified by:
isNew in interface javax.servlet.http.HttpSession
-
-
-
-
-
-
- -

-putValue

-
-public void putValue(java.lang.String string,
-                     java.lang.Object object)
-
-
-
Specified by:
putValue in interface javax.servlet.http.HttpSession
-
-
-
-
-
-
- -

-removeAttribute

-
-public void removeAttribute(java.lang.String string)
-
-
-
Specified by:
removeAttribute in interface javax.servlet.http.HttpSession
-
-
-
-
-
-
- -

-removeValue

-
-public void removeValue(java.lang.String string)
-
-
-
Specified by:
removeValue in interface javax.servlet.http.HttpSession
-
-
-
-
-
-
- -

-setAttribute

-
-public void setAttribute(java.lang.String string,
-                         java.lang.Object object)
-
-
-
Specified by:
setAttribute in interface javax.servlet.http.HttpSession
-
-
-
-
-
-
- -

-setMaxInactiveInterval

-
-public void setMaxInactiveInterval(int i)
-
-
-
Specified by:
setMaxInactiveInterval in interface javax.servlet.http.HttpSession
-
-
-
-
-
-
- -

-setAccessedTime

-
-public void setAccessedTime(long time)
-
-
-
-
-
-
-
-
-
- -

-setCreationTime

-
-public void setCreationTime(long time)
-
-
-
-
-
-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/http/TestRequestDispatcher.html b/javadoc/org/owasp/esapi/http/TestRequestDispatcher.html deleted file mode 100644 index 8c301e609..000000000 --- a/javadoc/org/owasp/esapi/http/TestRequestDispatcher.html +++ /dev/null @@ -1,294 +0,0 @@ - - - - - - -TestRequestDispatcher - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.http -
-Class TestRequestDispatcher

-
-java.lang.Object
-  extended byorg.owasp.esapi.http.TestRequestDispatcher
-
-
-
All Implemented Interfaces:
javax.servlet.RequestDispatcher
-
-
-
-
public class TestRequestDispatcher
extends java.lang.Object
implements javax.servlet.RequestDispatcher
- -

-


- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
TestRequestDispatcher() - -
-           
-  - - - - - - - - - - - - - - - -
-Method Summary
- voidforward(javax.servlet.ServletRequest request, - javax.servlet.ServletResponse response) - -
-           
- voidinclude(javax.servlet.ServletRequest request, - javax.servlet.ServletResponse response) - -
-           
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-TestRequestDispatcher

-
-public TestRequestDispatcher()
-
-
- - - - - - - - -
-Method Detail
- -

-forward

-
-public void forward(javax.servlet.ServletRequest request,
-                    javax.servlet.ServletResponse response)
-             throws javax.servlet.ServletException,
-                    java.io.IOException
-
-
-
Specified by:
forward in interface javax.servlet.RequestDispatcher
-
-
- -
Throws: -
javax.servlet.ServletException -
java.io.IOException
-
-
-
- -

-include

-
-public void include(javax.servlet.ServletRequest request,
-                    javax.servlet.ServletResponse response)
-             throws javax.servlet.ServletException,
-                    java.io.IOException
-
-
-
Specified by:
include in interface javax.servlet.RequestDispatcher
-
-
- -
Throws: -
javax.servlet.ServletException -
java.io.IOException
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/http/TestServletInputStream.html b/javadoc/org/owasp/esapi/http/TestServletInputStream.html deleted file mode 100644 index 63fa645fb..000000000 --- a/javadoc/org/owasp/esapi/http/TestServletInputStream.html +++ /dev/null @@ -1,279 +0,0 @@ - - - - - - -TestServletInputStream - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.http -
-Class TestServletInputStream

-
-java.lang.Object
-  extended byjava.io.InputStream
-      extended byjavax.servlet.ServletInputStream
-          extended byorg.owasp.esapi.http.TestServletInputStream
-
-
-
-
public class TestServletInputStream
extends javax.servlet.ServletInputStream
- -

-


- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
TestServletInputStream(byte[] body) - -
-          constructor
-  - - - - - - - - - - - -
-Method Summary
- intread() - -
-          read
- - - - - - - -
Methods inherited from class javax.servlet.ServletInputStream
readLine
- - - - - - - -
Methods inherited from class java.io.InputStream
available, close, mark, markSupported, read, read, reset, skip
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-TestServletInputStream

-
-public TestServletInputStream(byte[] body)
-
-
constructor -

-

Parameters:
body -
- - - - - - - - -
-Method Detail
- -

-read

-
-public int read()
-         throws java.io.IOException
-
-
read -

-

- -
Throws: -
java.io.IOException
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/http/class-use/TestFilterChain.html b/javadoc/org/owasp/esapi/http/class-use/TestFilterChain.html deleted file mode 100644 index 14ae2ccaa..000000000 --- a/javadoc/org/owasp/esapi/http/class-use/TestFilterChain.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.http.TestFilterChain - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.http.TestFilterChain

-
-No usage of org.owasp.esapi.http.TestFilterChain -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/http/class-use/TestHttpServletRequest.html b/javadoc/org/owasp/esapi/http/class-use/TestHttpServletRequest.html deleted file mode 100644 index 17231d733..000000000 --- a/javadoc/org/owasp/esapi/http/class-use/TestHttpServletRequest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.http.TestHttpServletRequest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.http.TestHttpServletRequest

-
-No usage of org.owasp.esapi.http.TestHttpServletRequest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/http/class-use/TestHttpServletResponse.html b/javadoc/org/owasp/esapi/http/class-use/TestHttpServletResponse.html deleted file mode 100644 index a11f232dc..000000000 --- a/javadoc/org/owasp/esapi/http/class-use/TestHttpServletResponse.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.http.TestHttpServletResponse - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.http.TestHttpServletResponse

-
-No usage of org.owasp.esapi.http.TestHttpServletResponse -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/http/class-use/TestHttpSession.html b/javadoc/org/owasp/esapi/http/class-use/TestHttpSession.html deleted file mode 100644 index 703d7a390..000000000 --- a/javadoc/org/owasp/esapi/http/class-use/TestHttpSession.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.http.TestHttpSession - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.http.TestHttpSession

-
-No usage of org.owasp.esapi.http.TestHttpSession -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/http/class-use/TestRequestDispatcher.html b/javadoc/org/owasp/esapi/http/class-use/TestRequestDispatcher.html deleted file mode 100644 index aaba2f8a4..000000000 --- a/javadoc/org/owasp/esapi/http/class-use/TestRequestDispatcher.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.http.TestRequestDispatcher - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.http.TestRequestDispatcher

-
-No usage of org.owasp.esapi.http.TestRequestDispatcher -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/http/class-use/TestServletInputStream.html b/javadoc/org/owasp/esapi/http/class-use/TestServletInputStream.html deleted file mode 100644 index 5eb4ec48c..000000000 --- a/javadoc/org/owasp/esapi/http/class-use/TestServletInputStream.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.http.TestServletInputStream - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.http.TestServletInputStream

-
-No usage of org.owasp.esapi.http.TestServletInputStream -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/http/package-frame.html b/javadoc/org/owasp/esapi/http/package-frame.html deleted file mode 100644 index 65f3915e9..000000000 --- a/javadoc/org/owasp/esapi/http/package-frame.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - -org.owasp.esapi.http - - - - - - - - - - - -org.owasp.esapi.http - - - - -
-Classes  - -
-TestFilterChain -
-TestHttpServletRequest -
-TestHttpServletResponse -
-TestHttpSession -
-TestRequestDispatcher -
-TestServletInputStream
- - - - diff --git a/javadoc/org/owasp/esapi/http/package-summary.html b/javadoc/org/owasp/esapi/http/package-summary.html deleted file mode 100644 index 2055da565..000000000 --- a/javadoc/org/owasp/esapi/http/package-summary.html +++ /dev/null @@ -1,188 +0,0 @@ - - - - - - -org.owasp.esapi.http - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-

-Package org.owasp.esapi.http -

-A few simple mock classes to help test the ESAPI reference -implementation. -

-See: -
-          Description -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Class Summary
TestFilterChain 
TestHttpServletRequestThe Class TestHttpServletRequest.
TestHttpServletResponseThe Class TestHttpServletResponse.
TestHttpSessionThe Class TestHttpSession.
TestRequestDispatcher 
TestServletInputStream 
-  - -

-

-Package org.owasp.esapi.http Description -

- -

-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. -

- -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/http/package-tree.html b/javadoc/org/owasp/esapi/http/package-tree.html deleted file mode 100644 index 0c4106cef..000000000 --- a/javadoc/org/owasp/esapi/http/package-tree.html +++ /dev/null @@ -1,154 +0,0 @@ - - - - - - -org.owasp.esapi.http Class Hierarchy - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Hierarchy For Package org.owasp.esapi.http -

-
-
-
Package Hierarchies:
All Packages
-
-

-Class Hierarchy -

-
    -
  • class java.lang.Object
      -
    • class java.io.InputStream -
    • class org.owasp.esapi.http.TestFilterChain (implements javax.servlet.FilterChain) -
    • class org.owasp.esapi.http.TestHttpServletRequest (implements javax.servlet.http.HttpServletRequest) -
    • class org.owasp.esapi.http.TestHttpServletResponse (implements javax.servlet.http.HttpServletResponse) -
    • class org.owasp.esapi.http.TestHttpSession (implements javax.servlet.http.HttpSession) -
    • class org.owasp.esapi.http.TestRequestDispatcher (implements javax.servlet.RequestDispatcher) -
    -
-
- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/http/package-use.html b/javadoc/org/owasp/esapi/http/package-use.html deleted file mode 100644 index 818cc238c..000000000 --- a/javadoc/org/owasp/esapi/http/package-use.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Package org.owasp.esapi.http - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Package
org.owasp.esapi.http

-
-No usage of org.owasp.esapi.http -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/IAccessController.html b/javadoc/org/owasp/esapi/interfaces/IAccessController.html deleted file mode 100644 index 4bd11fdf9..000000000 --- a/javadoc/org/owasp/esapi/interfaces/IAccessController.html +++ /dev/null @@ -1,469 +0,0 @@ - - - - - - -IAccessController - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.interfaces -
-Interface IAccessController

-
-
All Known Implementing Classes:
AccessController
-
-
-
-
public interface IAccessController
- -

-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. - -
- <% if ( ESAPI.accessController().isAuthorizedForFunction( ADMIN_FUNCTION ) ) { %>
- <a href="/doAdminFunction">ADMIN</a>
- <% } else { %>
- <a href="/doNormalFunction">NORMAL</a>
- <% } %>
- 
-

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- voidassertAuthorizedForData(java.lang.String key) - -
-           
- voidassertAuthorizedForFile(java.lang.String filepath) - -
-           
- voidassertAuthorizedForFunction(java.lang.String functionName) - -
-           
- voidassertAuthorizedForService(java.lang.String serviceName) - -
-           
- voidassertAuthorizedForURL(java.lang.String url) - -
-           
- booleanisAuthorizedForData(java.lang.String key) - -
-          Checks if an account is authorized to access the referenced data.
- booleanisAuthorizedForFile(java.lang.String filepath) - -
-          Checks if an account is authorized to access the referenced file.
- booleanisAuthorizedForFunction(java.lang.String functionName) - -
-          Checks if an account is authorized to access the referenced function.
- booleanisAuthorizedForService(java.lang.String serviceName) - -
-          Checks if an account is authorized to access the referenced service.
- booleanisAuthorizedForURL(java.lang.String url) - -
-          Checks if an account is authorized to access the referenced URL.
-  -

- - - - - - - - - - - - - - -
-Method Detail
- -

-isAuthorizedForURL

-
-public boolean isAuthorizedForURL(java.lang.String url)
-
-
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: -
ESAPI.accessController().isAuthorizedForURL(request.getRequestURI().toString());
-

-

- -
Returns:
true, if is authorized for URL
-
-
-
- -

-isAuthorizedForFunction

-
-public boolean isAuthorizedForFunction(java.lang.String functionName)
-
-
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. -

-

-
Parameters:
functionName - the function name -
Returns:
true, if is authorized for function
-
-
-
- -

-isAuthorizedForData

-
-public boolean isAuthorizedForData(java.lang.String key)
-
-
Checks if an account is authorized to access the referenced data. The implementation should define the data - "namespace" to be enforced. -

-

-
Parameters:
key - the key -
Returns:
true, if is authorized for data
-
-
-
- -

-isAuthorizedForFile

-
-public boolean isAuthorizedForFile(java.lang.String filepath)
-
-
Checks if an account is authorized to access the referenced file. The implementation should be extremely careful - about canonicalization. -

-

-
Parameters:
filepath - the filepath -
Returns:
true, if is authorized for file
-
-
-
- -

-isAuthorizedForService

-
-public boolean isAuthorizedForService(java.lang.String serviceName)
-
-
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. -

-

-
Parameters:
serviceName - the service name -
Returns:
true, if is authorized for service
-
-
-
- -

-assertAuthorizedForURL

-
-public void assertAuthorizedForURL(java.lang.String url)
-                            throws AccessControlException
-
-
- -
Throws: -
AccessControlException
-
-
-
- -

-assertAuthorizedForFunction

-
-public void assertAuthorizedForFunction(java.lang.String functionName)
-                                 throws AccessControlException
-
-
- -
Throws: -
AccessControlException
-
-
-
- -

-assertAuthorizedForData

-
-public void assertAuthorizedForData(java.lang.String key)
-                             throws AccessControlException
-
-
- -
Throws: -
AccessControlException
-
-
-
- -

-assertAuthorizedForFile

-
-public void assertAuthorizedForFile(java.lang.String filepath)
-                             throws AccessControlException
-
-
- -
Throws: -
AccessControlException
-
-
-
- -

-assertAuthorizedForService

-
-public void assertAuthorizedForService(java.lang.String serviceName)
-                                throws AccessControlException
-
-
- -
Throws: -
AccessControlException
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/IAccessReferenceMap.html b/javadoc/org/owasp/esapi/interfaces/IAccessReferenceMap.html deleted file mode 100644 index 8a9acfcc5..000000000 --- a/javadoc/org/owasp/esapi/interfaces/IAccessReferenceMap.html +++ /dev/null @@ -1,359 +0,0 @@ - - - - - - -IAccessReferenceMap - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.interfaces -
-Interface IAccessReferenceMap

-
-
All Known Implementing Classes:
AccessReferenceMap
-
-
-
-
public interface 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. 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.StringaddDirectReference(java.lang.Object direct) - -
-          Adds a direct reference to the AccessReferenceMap and generates an associated indirect reference.
- java.lang.ObjectgetDirectReference(java.lang.String indirectReference) - -
-          Get the original direct object reference from an indirect reference.
- java.lang.StringgetIndirectReference(java.lang.Object directReference) - -
-          Get a safe indirect reference to use in place of a potentially sensitive - direct object reference.
- java.util.Iteratoriterator() - -
-          Get an iterator through the direct object references.
- java.lang.StringremoveDirectReference(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. -

-

- -
Returns:
the iterator
-
-
-
- -

-getIndirectReference

-
-public java.lang.String getIndirectReference(java.lang.Object directReference)
-
-
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. -

-

-
Parameters:
directReference - the direct reference -
Returns:
the indirect reference
-
-
-
- -

-getDirectReference

-
-public java.lang.Object getDirectReference(java.lang.String indirectReference)
-                                    throws AccessControlException
-
-
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. -

-

-
Parameters:
indirectReference - the indirect reference -
Returns:
the direct reference -
Throws: -
AccessControlException - the access control exception
-
-
-
- -

-addDirectReference

-
-public java.lang.String addDirectReference(java.lang.Object direct)
-
-
Adds a direct reference to the AccessReferenceMap and generates an associated indirect reference. -

-

-
Parameters:
direct -
-
-
-
- -

-removeDirectReference

-
-public java.lang.String removeDirectReference(java.lang.Object direct)
-                                       throws AccessControlException
-
-
Removes a direct reference and its associated indirect reference from the AccessReferenceMap. -

-

-
Parameters:
direct - -
Throws: -
AccessControlException
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/IAuthenticator.html b/javadoc/org/owasp/esapi/interfaces/IAuthenticator.html deleted file mode 100644 index f2a577f32..000000000 --- a/javadoc/org/owasp/esapi/interfaces/IAuthenticator.html +++ /dev/null @@ -1,600 +0,0 @@ - - - - - - -IAuthenticator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.interfaces -
-Interface IAuthenticator

-
-
All Known Implementing Classes:
Authenticator
-
-
-
-
public interface IAuthenticator
- -

-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
- voidclearCurrent() - -
-          Clear the current user, request, and response.
- IUsercreateUser(java.lang.String accountName, - java.lang.String password1, - java.lang.String password2) - -
-          Creates the user.
- booleanexists(java.lang.String accountName) - -
-          Verifies the account exists.
- java.lang.StringgenerateStrongPassword() - -
-          Generate a strong password.
- java.lang.StringgenerateStrongPassword(java.lang.String oldPassword, - IUser user) - -
-          Generate strong password that takes into account the user's information and old password.
- IUsergetCurrentUser() - -
-          Returns the currently logged in User.
- IUsergetUser(java.lang.String accountName) - -
-          Returns the User matching the provided accountName.
- java.util.SetgetUserNames() - -
-          Gets the user names.
- java.lang.StringhashPassword(java.lang.String password, - java.lang.String accountName) - -
-          Returns a string representation of the hashed password, using the - accountName as the salt.
- IUserlogin(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.
- voidlogout() - -
-          Logs out the current user.
- voidremoveUser(java.lang.String accountName) - -
-          Removes the account.
- voidsetCurrentUser(IUser user) - -
-          Sets the currently logged in User.
- voidverifyAccountNameStrength(java.lang.String accountName) - -
-          Validate password strength.
- voidverifyPasswordStrength(java.lang.String newPassword, - java.lang.String oldPassword) - -
-          Validate password strength.
-  -

- - - - - - - - - - - - - - -
-Method Detail
- -

-clearCurrent

-
-public void clearCurrent()
-
-
Clear the current user, request, and response. This allows the thread to be reused safely. -

-

-
-
-
-
- -

-login

-
-public IUser login(javax.servlet.http.HttpServletRequest request,
-                   javax.servlet.http.HttpServletResponse response)
-            throws AuthenticationException
-
-
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 - the authentication exception
-
-
-
- -

-logout

-
-public void logout()
-
-
Logs out the current user. -

-

-
-
-
-
- -

-createUser

-
-public IUser createUser(java.lang.String accountName,
-                        java.lang.String password1,
-                        java.lang.String password2)
-                 throws AuthenticationException
-
-
Creates the user. -

-

-
Parameters:
accountName - the account name
password1 - the password
password2 - copy of the password -
Returns:
the new User object -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-generateStrongPassword

-
-public java.lang.String generateStrongPassword()
-
-
Generate a strong password. -

-

- -
Returns:
the string
-
-
-
- -

-generateStrongPassword

-
-public java.lang.String generateStrongPassword(java.lang.String oldPassword,
-                                               IUser user)
-
-
Generate strong password that takes into account the user's information and old password. -

-

-
Parameters:
oldPassword - the old password
user - the user -
Returns:
the string
-
-
-
- -

-getUser

-
-public IUser getUser(java.lang.String accountName)
-
-
Returns the User matching the provided accountName. -

-

-
Parameters:
accountName - the account name -
Returns:
the matching User object, or null if no match exists
-
-
-
- -

-getUserNames

-
-public java.util.Set getUserNames()
-
-
Gets the user names. -

-

- -
Returns:
the user names
-
-
-
- -

-getCurrentUser

-
-public IUser getCurrentUser()
-
-
Returns the currently logged in User. -

-

- -
Returns:
the matching User object, or the Anonymous user if no match - exists
-
-
-
- -

-setCurrentUser

-
-public void setCurrentUser(IUser user)
-
-
Sets the currently logged in User. -

-

-
Parameters:
user - the current user
-
-
-
- -

-hashPassword

-
-public java.lang.String hashPassword(java.lang.String password,
-                                     java.lang.String accountName)
-                              throws EncryptionException
-
-
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. -

-

-
Parameters:
password - the password
accountName - the account name -
Returns:
the string -
Throws: -
EncryptionException
-
-
-
- -

-removeUser

-
-public void removeUser(java.lang.String accountName)
-                throws AuthenticationException
-
-
Removes the account. -

-

-
Parameters:
accountName - the account name -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-verifyAccountNameStrength

-
-public void verifyAccountNameStrength(java.lang.String accountName)
-                               throws AuthenticationException
-
-
Validate password strength. -

-

-
Parameters:
accountName - the account name -
Returns:
true, if successful -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-verifyPasswordStrength

-
-public void verifyPasswordStrength(java.lang.String newPassword,
-                                   java.lang.String oldPassword)
-                            throws AuthenticationException
-
-
Validate password strength. -

-

-
Parameters:
newPassword - the new password
oldPassword - the old password -
Returns:
true, if successful -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-exists

-
-public boolean exists(java.lang.String accountName)
-
-
Verifies the account exists. -

-

-
Parameters:
accountName - the account name -
Returns:
true, if successful
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/IEncoder.html b/javadoc/org/owasp/esapi/interfaces/IEncoder.html deleted file mode 100644 index d7d40c733..000000000 --- a/javadoc/org/owasp/esapi/interfaces/IEncoder.html +++ /dev/null @@ -1,675 +0,0 @@ - - - - - - -IEncoder - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.interfaces -
-Interface IEncoder

-
-
All Known Implementing Classes:
Encoder
-
-
-
-
public interface IEncoder
- -

-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.Stringcanonicalize(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.StringdecodeFromURL(java.lang.String input) - -
-          Decode from URL.
- java.lang.StringencodeForBase64(byte[] input, - boolean wrap) - -
-          Encode for base64.
- java.lang.StringencodeForDN(java.lang.String input) - -
-          Encode data for use in an LDAP distinguished name.
- java.lang.StringencodeForHTML(java.lang.String input) - -
-          Encode data for use in HTML content.
- java.lang.StringencodeForHTMLAttribute(java.lang.String input) - -
-          Encode data for use in HTML attributes.
- java.lang.StringencodeForJavascript(java.lang.String input) - -
-          Encode for javascript.
- java.lang.StringencodeForLDAP(java.lang.String input) - -
-          Encode data for use in LDAP queries.
- java.lang.StringencodeForSQL(java.lang.String input) - -
-          Encode for SQL.
- java.lang.StringencodeForURL(java.lang.String input) - -
-          Encode for use in a URL.
- java.lang.StringencodeForVBScript(java.lang.String input) - -
-          Encode data for use in visual basic script.
- java.lang.StringencodeForXML(java.lang.String input) - -
-          Encode data for use in an XML element.
- java.lang.StringencodeForXMLAttribute(java.lang.String input) - -
-          Encode data for use in an XML attribute.
- java.lang.StringencodeForXPath(java.lang.String input) - -
-          Encode data for use in an XPath query.
- java.lang.Stringnormalize(java.lang.String input) - -
-          Reduce all non-ascii characters to their ASCII form so that simpler - validation rules can be applied.
-  -

- - - - - - - - - - - - - - -
-Method Detail
- -

-canonicalize

-
-public java.lang.String canonicalize(java.lang.String input)
-                              throws EncodingException
-
-
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. -

-

-
Parameters:
input - unvalidated input from an HTTP request -
Returns:
the canonicalized string -
Throws: -
IntrusionException - if there is a canonicalization problem -
EncodingException
-
-
-
- -

-normalize

-
-public 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. For example, an accented-e character - will be changed into a regular ASCII e character. -

-

-
Parameters:
input - -
Returns:
-
-
-
- -

-encodeForHTML

-
-public java.lang.String encodeForHTML(java.lang.String input)
-
-
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. -

-

-
Parameters:
input - the input -
Returns:
the string
-
-
-
- -

-encodeForHTMLAttribute

-
-public java.lang.String encodeForHTMLAttribute(java.lang.String input)
-
-
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. -

-

-
Parameters:
input - the input -
Returns:
the string
-
-
-
- -

-encodeForJavascript

-
-public java.lang.String encodeForJavascript(java.lang.String input)
-
-
Encode for javascript. This method first canonicalizes and detects any - double-encoding. If this check passes, then the data is encoded using a - whitelist. -

-

-
Parameters:
input - the input -
Returns:
the string
-
-
-
- -

-encodeForVBScript

-
-public java.lang.String encodeForVBScript(java.lang.String input)
-
-
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. -

-

-
Parameters:
input - the input -
Returns:
the string
-
-
-
- -

-encodeForSQL

-
-public java.lang.String encodeForSQL(java.lang.String input)
-
-
Encode for SQL. This method first canonicalizes and detects any - double-encoding. If this check passes, then the data is encoded using a - whitelist. -

-

-
Parameters:
input - the input -
Returns:
the string
-
-
-
- -

-encodeForLDAP

-
-public java.lang.String encodeForLDAP(java.lang.String input)
-
-
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. -

-

-
Parameters:
input - the input -
Returns:
the string
-
-
-
- -

-encodeForDN

-
-public java.lang.String encodeForDN(java.lang.String input)
-
-
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. -

-

-
Parameters:
input - the input -
Returns:
the string
-
-
-
- -

-encodeForXPath

-
-public java.lang.String encodeForXPath(java.lang.String input)
-
-
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. -

-

-
Parameters:
input - the input -
Returns:
the string
-
-
-
- -

-encodeForXML

-
-public java.lang.String encodeForXML(java.lang.String input)
-
-
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. -

-

-
Parameters:
input - the input -
Returns:
the string
-
-
-
- -

-encodeForXMLAttribute

-
-public java.lang.String encodeForXMLAttribute(java.lang.String input)
-
-
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. -

-

-
Parameters:
input - the input -
Returns:
the string
-
-
-
- -

-encodeForURL

-
-public java.lang.String encodeForURL(java.lang.String input)
-                              throws EncodingException
-
-
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. -

-

-
Parameters:
input - the input -
Returns:
the string -
Throws: -
EncodingException
-
-
-
- -

-decodeFromURL

-
-public java.lang.String decodeFromURL(java.lang.String input)
-                               throws EncodingException
-
-
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. -
EncodingException
-
-
-
- -

-encodeForBase64

-
-public java.lang.String encodeForBase64(byte[] input,
-                                        boolean wrap)
-
-
Encode for base64. -

- Beware double-encoding, as this will corrupt the results and could - possibly cause a downstream security mechansim to make a mistake. -

-

-
Parameters:
input - the input -
Returns:
the string
-
-
-
- -

-decodeFromBase64

-
-public byte[] decodeFromBase64(java.lang.String input)
-                        throws java.io.IOException
-
-
Decode data encoded with BASE-64 encoding. -

- Beware double-encoded data, as the results of this method could still - contain encoded characters as part of attacks. -

-

-
Parameters:
input - the input -
Returns:
the byte[] -
Throws: -
java.io.IOException - Signals that an I/O exception has occurred.
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/IEncryptedProperties.html b/javadoc/org/owasp/esapi/interfaces/IEncryptedProperties.html deleted file mode 100644 index 2525d37a9..000000000 --- a/javadoc/org/owasp/esapi/interfaces/IEncryptedProperties.html +++ /dev/null @@ -1,263 +0,0 @@ - - - - - - -IEncryptedProperties - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.interfaces -
-Interface IEncryptedProperties

-
-
All Known Implementing Classes:
EncryptedProperties
-
-
-
-
public interface IEncryptedProperties
- -

-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.StringgetProperty(java.lang.String key) - -
-          Gets the property value from the encrypted store, decrypts it, and returns the plaintext value to the caller.
- java.lang.StringsetProperty(java.lang.String key, - java.lang.String value) - -
-          Encrypts the plaintext property value and stores the ciphertext value in the encrypted store.
-  -

- - - - - - - - - - - - - - -
-Method Detail
- -

-getProperty

-
-public java.lang.String getProperty(java.lang.String key)
-                             throws EncryptionException
-
-
Gets the property value from the encrypted store, decrypts it, and returns the plaintext value to the caller. -

-

-
Parameters:
key - the key -
Returns:
the property -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-setProperty

-
-public java.lang.String setProperty(java.lang.String key,
-                                    java.lang.String value)
-                             throws EncryptionException
-
-
Encrypts the plaintext property value and stores the ciphertext value in the encrypted store. -

-

-
Parameters:
key - the key
value - the value -
Returns:
the object -
Throws: -
EncryptionException - the encryption exception
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/IEncryptor.html b/javadoc/org/owasp/esapi/interfaces/IEncryptor.html deleted file mode 100644 index 05fdbcd95..000000000 --- a/javadoc/org/owasp/esapi/interfaces/IEncryptor.html +++ /dev/null @@ -1,488 +0,0 @@ - - - - - - -IEncryptor - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.interfaces -
-Interface IEncryptor

-
-
All Known Implementing Classes:
Encryptor
-
-
-
-
public interface IEncryptor
- -

-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.Stringdecrypt(java.lang.String ciphertext) - -
-          Decrypts the provided ciphertext string (encrypted with the encrypt - method) and returns a plaintext string.
- java.lang.Stringencrypt(java.lang.String plaintext) - -
-          Encrypts the provided plaintext and returns a ciphertext string.
- longgetRelativeTimeStamp(long offset) - -
-          Gets a timestamp representing an offset from the current time to be used by - other functions in the library.
- longgetTimeStamp() - -
-          Gets a timestamp representing the current date and time to be used by - other functions in the library.
- java.lang.Stringhash(java.lang.String plaintext, - java.lang.String salt) - -
-          Returns a string representation of the hash of the provided plaintext and - salt.
- java.lang.Stringseal(java.lang.String data, - long timestamp) - -
-          Creates a seal that binds a set of data and an expiration timestamp.
- java.lang.Stringsign(java.lang.String data) - -
-          Create a digital signature for the provided data and return it in a - string.
- java.lang.Stringunseal(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.
- booleanverifySeal(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.
- booleanverifySignature(java.lang.String signature, - java.lang.String data) - -
-          Verifies a digital signature (created with the sign method) and returns - the boolean result.
-  -

- - - - - - - - - - - - - - -
-Method Detail
- -

-hash

-
-public java.lang.String hash(java.lang.String plaintext,
-                             java.lang.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. -

-

-
Parameters:
plaintext - the plaintext
salt - the salt -
Returns:
the string -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-encrypt

-
-public java.lang.String encrypt(java.lang.String plaintext)
-                         throws EncryptionException
-
-
Encrypts the provided plaintext and returns a ciphertext string. -

-

-
Parameters:
plaintext - the plaintext -
Returns:
the string -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-decrypt

-
-public java.lang.String decrypt(java.lang.String ciphertext)
-                         throws EncryptionException
-
-
Decrypts the provided ciphertext string (encrypted with the encrypt - method) and returns a plaintext string. -

-

-
Parameters:
ciphertext - the ciphertext -
Returns:
the string -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-sign

-
-public java.lang.String sign(java.lang.String data)
-                      throws EncryptionException
-
-
Create a digital signature for the provided data and return it in a - string. -

-

-
Parameters:
data - the data -
Returns:
the string -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-verifySignature

-
-public boolean verifySignature(java.lang.String signature,
-                               java.lang.String data)
-
-
Verifies a digital signature (created with the sign method) and returns - the boolean result. -

-

-
Parameters:
signature - the signature
data - the data -
Returns:
true, if successful -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-seal

-
-public java.lang.String seal(java.lang.String data,
-                             long timestamp)
-                      throws IntegrityException
-
-
Creates a seal that binds a set of data and an expiration timestamp. -

-

-
Parameters:
data - the data
timestamp - the timestamp of the expiration date of the data. -
Returns:
the string -
Throws: -
EncryptionException - the encryption exception -
IntegrityException
-
-
-
- -

-unseal

-
-public java.lang.String unseal(java.lang.String seal)
-                        throws EncryptionException
-
-
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 seal -
Throws: -
EncryptionException
-
-
-
- -

-verifySeal

-
-public 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. -

-

-
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. -

-

- -
Returns:
the timestamp
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/IExecutor.html b/javadoc/org/owasp/esapi/interfaces/IExecutor.html deleted file mode 100644 index 7f163c1b5..000000000 --- a/javadoc/org/owasp/esapi/interfaces/IExecutor.html +++ /dev/null @@ -1,253 +0,0 @@ - - - - - - -IExecutor - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.interfaces -
-Interface IExecutor

-
-
All Known Implementing Classes:
Executor
-
-
-
-
public interface IExecutor
- -

-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.StringexecuteSystemCommand(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.
-  -

- - - - - - - - - - - - - - -
-Method Detail
- -

-executeSystemCommand

-
-public java.lang.String executeSystemCommand(java.io.File executable,
-                                             java.util.List params,
-                                             java.io.File workdir,
-                                             int timeoutSeconds)
-                                      throws ExecutorException
-
-
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 params
workdir - the workdir
timeoutSeconds - the timeout seconds -
Returns:
the string -
Throws: -
ExecutorException - the service exception
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/IHTTPUtilities.html b/javadoc/org/owasp/esapi/interfaces/IHTTPUtilities.html deleted file mode 100644 index c3656a045..000000000 --- a/javadoc/org/owasp/esapi/interfaces/IHTTPUtilities.html +++ /dev/null @@ -1,918 +0,0 @@ - - - - - - -IHTTPUtilities - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.interfaces -
-Interface IHTTPUtilities

-
-
All Known Implementing Classes:
HTTPUtilities
-
-
-
-
public interface IHTTPUtilities
- -

-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.StringaddCSRFToken(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.HttpSessionchangeSessionIdentifier() - -
-          Invalidate the old session after copying all of its contents to a newly created session with a new session id.
- java.lang.StringdecryptHiddenField(java.lang.String encrypted) - -
-          Decrypts an encrypted hidden field value and returns the cleartest.
- java.util.MapdecryptQueryString(java.lang.String encrypted) - -
-          Takes an encrypted querystring and returns a Map containing the original parameters.
- java.util.MapdecryptStateFromCookie() - -
-          Retrieves a map of data from the encrypted cookie.
- voidenableRememberToken(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.StringencryptHiddenField(java.lang.String value) - -
-          Encrypts a hidden field value for use in HTML.
- java.lang.StringencryptQueryString(java.lang.String query) - -
-          Takes a querystring (i.e.
- voidencryptStateInCookie(java.util.Map cleartext) - -
-          Stores a Map of data in an encrypted cookie.
- java.lang.StringgetCookie(java.lang.String name) - -
-          Returns the first cookie matching the given name.
- javax.servlet.http.HttpServletRequestgetCurrentRequest() - -
-          Retrieves the current HttpServletRequest
- javax.servlet.http.HttpServletResponsegetCurrentResponse() - -
-          Retrieves the current HttpServletResponse
- java.util.ListgetSafeFileUploads(java.io.File tempDir, - java.io.File finalDir) - -
-          Extract uploaded files from a multipart HTTP requests.
- booleanisSecureChannel() - -
-          Returns true if the request and response are using an SSL-enabled connection.
- voidkillAllCookies() - -
-          Kill all cookies received in the last request from the browser.
- voidkillCookie(java.lang.String name) - -
-          Kills the specified cookie by setting a new cookie that expires immediately.
- voidlogHTTPRequest(ILogger logger) - -
-          Format the Source IP address, URL, URL parameters, and all form - parameters into a string suitable for the log file.
- voidlogHTTPRequest(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.
- voidsafeAddCookie(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.
- voidsafeAddHeader(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.
- voidsafeSendForward(java.lang.String context, - java.lang.String location) - -
-          This method perform a forward to any resource located inside the WEB-INF directory.
- voidsafeSendRedirect(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.
- voidsafeSetContentType() - -
-          Sets the content type on each HTTP response, to help protect against cross-site scripting attacks and other types - of injection into HTML documents.
- voidsafeSetHeader(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.
- voidsetCurrentHTTP(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)
- voidsetNoCacheHeaders() - -
-          Set headers to protect sensitive information against being cached in the browser.
- voidverifyCSRFToken() - -
-          Checks the CSRF token in the URL (see User.getCSRFToken()) against the user's CSRF token and - throws an IntrusionException if it is missing.
-  -

- - - - - - - - - - - - - - -
-Method Detail
- -

-addCSRFToken

-
-public 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. - This method should be used on all URLs to be put into all links and forms the application generates. -

-

- -
Returns:
the updated href with the CSRF token parameter
-
-
-
- -

-safeAddCookie

-
-public 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. -

-

-
Parameters:
name - the name
value - the value
domain - the domain
path - the path
maxAge - the max age
-
-
-
- -

-safeAddHeader

-
-public void safeAddHeader(java.lang.String name,
-                          java.lang.String value)
-                   throws ValidationException
-
-
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. -

-

-
Parameters:
name - the name
value - the value -
Throws: -
ValidationException
-
-
-
- -

-safeSetHeader

-
-public void safeSetHeader(java.lang.String name,
-                          java.lang.String value)
-                   throws ValidationException
-
-
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. -

-

-
Parameters:
name - the name
value - the value -
Throws: -
ValidationException
-
-
-
- -

-changeSessionIdentifier

-
-public javax.servlet.http.HttpSession changeSessionIdentifier()
-                                                       throws AuthenticationException
-
-
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. -

-

- -
Returns:
the http session -
Throws: -
EnterpriseSecurityException - the enterprise security exception -
AuthenticationException
-
-
-
- -

-verifyCSRFToken

-
-public void verifyCSRFToken()
-                     throws IntrusionException
-
-
Checks the CSRF token in the URL (see User.getCSRFToken()) against the user's CSRF token and - throws an IntrusionException if it is missing. -

-

- -
Throws: -
IntrusionException
-
-
-
- -

-decryptHiddenField

-
-public java.lang.String decryptHiddenField(java.lang.String encrypted)
-
-
Decrypts an encrypted hidden field value and returns the cleartest. If the field does not decrypt properly, - an IntrusionException is thrown to indicate tampering. -

-

-
Parameters:
encrypted - -
Returns:
-
-
-
- -

-enableRememberToken

-
-public void enableRememberToken(int maxAge,
-                                java.lang.String domain,
-                                java.lang.String path)
-
-
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. -

-

-
Parameters:
maxAge -
domain -
path -
-
-
-
- -

-encryptHiddenField

-
-public java.lang.String encryptHiddenField(java.lang.String value)
-                                    throws EncryptionException
-
-
Encrypts a hidden field value for use in HTML. -

-

-
Parameters:
value - -
Returns:
-
Throws: -
EncryptionException
-
-
-
- -

-encryptQueryString

-
-public java.lang.String encryptQueryString(java.lang.String query)
-                                    throws EncryptionException
-
-
Takes a querystring (i.e. everything after the ? in the URL) and returns an encrypted string containing the parameters. -

-

- -
Returns:
-
Throws: -
EncryptionException
-
-
-
- -

-decryptQueryString

-
-public java.util.Map decryptQueryString(java.lang.String encrypted)
-                                 throws EncryptionException
-
-
Takes an encrypted querystring and returns a Map containing the original parameters. -

-

-
Parameters:
encrypted - -
Returns:
-
Throws: -
EncryptionException
-
-
-
- -

-getCookie

-
-public java.lang.String getCookie(java.lang.String name)
-
-
Returns the first cookie matching the given name. -

-

-
-
-
-
- -

-getSafeFileUploads

-
-public java.util.List getSafeFileUploads(java.io.File tempDir,
-                                         java.io.File finalDir)
-                                  throws ValidationException
-
-
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. -

-

-
Parameters:
tempDir - the temp dir
finalDir - the final dir -
Returns:
List of new File objects from upload -
Throws: -
ValidationException - the validation exception
-
-
-
- -

-decryptStateFromCookie

-
-public java.util.Map decryptStateFromCookie()
-                                     throws EncryptionException
-
-
Retrieves a map of data from the encrypted cookie. -

-

- -
Throws: -
EncryptionException
-
-
-
- -

-isSecureChannel

-
-public boolean isSecureChannel()
-
-
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. -

-

-
Parameters:
name - the cookie name
-
-
-
- -

-encryptStateInCookie

-
-public void encryptStateInCookie(java.util.Map cleartext)
-                          throws EncryptionException
-
-
Stores a Map of data in an encrypted cookie. -

-

- -
Throws: -
EncryptionException
-
-
-
- -

-safeSendRedirect

-
-public void safeSendRedirect(java.lang.String context,
-                             java.lang.String location)
-                      throws java.io.IOException
-
-
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.
-
-
-
- -

-safeSendForward

-
-public void safeSendForward(java.lang.String context,
-                            java.lang.String location)
-                     throws AccessControlException,
-                            javax.servlet.ServletException,
-                            java.io.IOException
-
-
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. -

-

-
Parameters:
context -
location - -
Throws: -
AccessControlException -
javax.servlet.ServletException -
java.io.IOException
-
-
-
- -

-safeSetContentType

-
-public 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. -

-

-
-
-
-
- -

-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: - -
- 
- Cache-Control: no-store
- Cache-Control: no-cache
- Cache-Control: must-revalidate
- Expires: -1
- -
- - 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: - -

-

-
-
-
-
- -

-setCurrentHTTP

-
-public 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) -

-

-
Parameters:
request - the current request
response - the current response
-
-
-
- -

-getCurrentRequest

-
-public javax.servlet.http.HttpServletRequest getCurrentRequest()
-
-
Retrieves the current HttpServletRequest -

-

- -
Returns:
the current request
-
-
-
- -

-getCurrentResponse

-
-public javax.servlet.http.HttpServletResponse getCurrentResponse()
-
-
Retrieves the current HttpServletResponse -

-

- -
Returns:
the current response
-
-
-
- -

-logHTTPRequest

-
-public void logHTTPRequest(ILogger logger)
-
-
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. -

-

-
-
-
-
- -

-logHTTPRequest

-
-public 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. 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. -

-

-
Parameters:
parameterNamesToObfuscate - the sensitive params
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/IIntrusionDetector.html b/javadoc/org/owasp/esapi/interfaces/IIntrusionDetector.html deleted file mode 100644 index c93433828..000000000 --- a/javadoc/org/owasp/esapi/interfaces/IIntrusionDetector.html +++ /dev/null @@ -1,262 +0,0 @@ - - - - - - -IIntrusionDetector - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.interfaces -
-Interface IIntrusionDetector

-
-
All Known Implementing Classes:
IntrusionDetector
-
-
-
-
public interface IIntrusionDetector
- -

-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
- voidaddEvent(java.lang.String eventName) - -
-          Adds the event to the IntrusionDetector.
- voidaddException(java.lang.Exception exception) - -
-          Adds the exception to the IntrusionDetector.
-  -

- - - - - - - - - - - - - - -
-Method Detail
- -

-addException

-
-public void addException(java.lang.Exception exception)
-                  throws IntrusionException
-
-
Adds the exception to the IntrusionDetector. -

-

-
Parameters:
exception - the exception -
Throws: -
IntrusionException - the intrusion exception
-
-
-
- -

-addEvent

-
-public void addEvent(java.lang.String eventName)
-              throws IntrusionException
-
-
Adds the event to the IntrusionDetector. -

-

-
Parameters:
eventName - the event -
Throws: -
IntrusionException - the intrusion exception
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/ILogFactory.html b/javadoc/org/owasp/esapi/interfaces/ILogFactory.html deleted file mode 100644 index 1e7967c97..000000000 --- a/javadoc/org/owasp/esapi/interfaces/ILogFactory.html +++ /dev/null @@ -1,238 +0,0 @@ - - - - - - -ILogFactory - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.interfaces -
-Interface ILogFactory

-
-
All Known Implementing Classes:
JavaLogFactory
-
-
-
-
public interface ILogFactory
- -

-

-
Author:
-
rdawes
-
-
- -

- - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- ILoggergetLogger(java.lang.Class clazz) - -
-           
- ILoggergetLogger(java.lang.String name) - -
-           
-  -

- - - - - - - - - - - - - - -
-Method Detail
- -

-getLogger

-
-public ILogger getLogger(java.lang.String name)
-
-
-
-
-
-
- -

-getLogger

-
-public ILogger getLogger(java.lang.Class clazz)
-
-
-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/ILogger.html b/javadoc/org/owasp/esapi/interfaces/ILogger.html deleted file mode 100644 index c2d4c2da9..000000000 --- a/javadoc/org/owasp/esapi/interfaces/ILogger.html +++ /dev/null @@ -1,727 +0,0 @@ - - - - - - -ILogger - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.interfaces -
-Interface ILogger

-
-
All Known Implementing Classes:
Logger
-
-
-
-
public interface ILogger
- -

-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
-
-
- -

- - - - - - - - - - - - - - - - - - - - - - -
-Field Summary
-static java.lang.StringPERFORMANCE - -
-          The PERFORMANCE.
-static java.lang.StringSECURITY - -
-          The SECURITY.
-static java.lang.StringUSABILITY - -
-          The USABILITY.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- voiddebug(java.lang.String type, - java.lang.String message) - -
-          Log debug.
- voiddebug(java.lang.String type, - java.lang.String message, - java.lang.Throwable throwable) - -
-          Log debug.
- voiderror(java.lang.String type, - java.lang.String message) - -
-          Log error.
- voiderror(java.lang.String type, - java.lang.String message, - java.lang.Throwable throwable) - -
-          Log error.
- voidfatal(java.lang.String type, - java.lang.String message) - -
-          Log critical.
- voidfatal(java.lang.String type, - java.lang.String message, - java.lang.Throwable throwable) - -
-          Log critical.
- voidinfo(java.lang.String type, - java.lang.String message) - -
-          Log success.
- voidinfo(java.lang.String type, - java.lang.String message, - java.lang.Throwable throwable) - -
-          Log success.
- booleanisDebugEnabled() - -
-          Allows the caller to determine if messages logged at this level - will be discarded, to avoid performing expensive processing
- booleanisErrorEnabled() - -
-          Allows the caller to determine if messages logged at this level - will be discarded, to avoid performing expensive processing
- booleanisFatalEnabled() - -
-          Allows the caller to determine if messages logged at this level - will be discarded, to avoid performing expensive processing
- booleanisInfoEnabled() - -
-          Allows the caller to determine if messages logged at this level - will be discarded, to avoid performing expensive processing
- booleanisTraceEnabled() - -
-          Allows the caller to determine if messages logged at this level - will be discarded, to avoid performing expensive processing
- booleanisWarningEnabled() - -
-          Allows the caller to determine if messages logged at this level - will be discarded, to avoid performing expensive processing
- voidtrace(java.lang.String type, - java.lang.String message) - -
-          Log trace.
- voidtrace(java.lang.String type, - java.lang.String message, - java.lang.Throwable throwable) - -
-          Log trace.
- voidwarning(java.lang.String type, - java.lang.String message) - -
-          Log warning.
- voidwarning(java.lang.String type, - java.lang.String message, - java.lang.Throwable throwable) - -
-          Log warning.
-  -

- - - - - - - - -
-Field Detail
- -

-SECURITY

-
-public static final java.lang.String SECURITY
-
-
The SECURITY. -

-

-
See Also:
Constant Field Values
-
-
- -

-USABILITY

-
-public static final java.lang.String USABILITY
-
-
The USABILITY. -

-

-
See Also:
Constant Field Values
-
-
- -

-PERFORMANCE

-
-public static final java.lang.String PERFORMANCE
-
-
The PERFORMANCE. -

-

-
See Also:
Constant Field Values
-
- - - - - - - - - - - -
-Method Detail
- -

-fatal

-
-public void fatal(java.lang.String type,
-                  java.lang.String message)
-
-
Log critical. -

-

-
Parameters:
type - the type
message - the message
-
-
-
- -

-fatal

-
-public void fatal(java.lang.String type,
-                  java.lang.String message,
-                  java.lang.Throwable throwable)
-
-
Log critical. -

-

-
Parameters:
type - the type
message - the message
throwable - the throwable
-
-
-
- -

-isFatalEnabled

-
-public boolean isFatalEnabled()
-
-
Allows the caller to determine if messages logged at this level - will be discarded, to avoid performing expensive processing -

-

- -
Returns:
true if messages will be output to the log
-
-
-
- -

-debug

-
-public void debug(java.lang.String type,
-                  java.lang.String message)
-
-
Log debug. -

-

-
Parameters:
type - the type
message - the message
-
-
-
- -

-debug

-
-public void debug(java.lang.String type,
-                  java.lang.String message,
-                  java.lang.Throwable throwable)
-
-
Log debug. -

-

-
Parameters:
type - the type
message - the message
throwable - the throwable
-
-
-
- -

-isDebugEnabled

-
-public boolean isDebugEnabled()
-
-
Allows the caller to determine if messages logged at this level - will be discarded, to avoid performing expensive processing -

-

- -
Returns:
true if messages will be output to the log
-
-
-
- -

-error

-
-public void error(java.lang.String type,
-                  java.lang.String message)
-
-
Log error. -

-

-
Parameters:
type - the type
message - the message
-
-
-
- -

-error

-
-public void error(java.lang.String type,
-                  java.lang.String message,
-                  java.lang.Throwable throwable)
-
-
Log error. -

-

-
Parameters:
type - the type
message - the message
throwable - the throwable
-
-
-
- -

-isErrorEnabled

-
-public boolean isErrorEnabled()
-
-
Allows the caller to determine if messages logged at this level - will be discarded, to avoid performing expensive processing -

-

- -
Returns:
true if messages will be output to the log
-
-
-
- -

-info

-
-public void info(java.lang.String type,
-                 java.lang.String message)
-
-
Log success. -

-

-
Parameters:
type - the type
message - the message
-
-
-
- -

-info

-
-public void info(java.lang.String type,
-                 java.lang.String message,
-                 java.lang.Throwable throwable)
-
-
Log success. -

-

-
Parameters:
type - the type
message - the message
throwable - the throwable
-
-
-
- -

-isInfoEnabled

-
-public boolean isInfoEnabled()
-
-
Allows the caller to determine if messages logged at this level - will be discarded, to avoid performing expensive processing -

-

- -
Returns:
true if messages will be output to the log
-
-
-
- -

-trace

-
-public void trace(java.lang.String type,
-                  java.lang.String message)
-
-
Log trace. -

-

-
Parameters:
type - the type
message - the message
-
-
-
- -

-trace

-
-public void trace(java.lang.String type,
-                  java.lang.String message,
-                  java.lang.Throwable throwable)
-
-
Log trace. -

-

-
Parameters:
type - the type
message - the message
throwable - the throwable
-
-
-
- -

-isTraceEnabled

-
-public boolean isTraceEnabled()
-
-
Allows the caller to determine if messages logged at this level - will be discarded, to avoid performing expensive processing -

-

- -
Returns:
true if messages will be output to the log
-
-
-
- -

-warning

-
-public void warning(java.lang.String type,
-                    java.lang.String message)
-
-
Log warning. -

-

-
Parameters:
type - the type
message - the message
-
-
-
- -

-warning

-
-public void warning(java.lang.String type,
-                    java.lang.String message,
-                    java.lang.Throwable throwable)
-
-
Log warning. -

-

-
Parameters:
type - the type
message - the message
throwable - the throwable
-
-
-
- -

-isWarningEnabled

-
-public boolean isWarningEnabled()
-
-
Allows the caller to determine if messages logged at this level - will be discarded, to avoid performing expensive processing -

-

- -
Returns:
true if messages will be output to the log
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/IRandomizer.html b/javadoc/org/owasp/esapi/interfaces/IRandomizer.html deleted file mode 100644 index a4c8181e9..000000000 --- a/javadoc/org/owasp/esapi/interfaces/IRandomizer.html +++ /dev/null @@ -1,354 +0,0 @@ - - - - - - -IRandomizer - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.interfaces -
-Interface IRandomizer

-
-
All Known Implementing Classes:
Randomizer
-
-
-
-
public interface IRandomizer
- -

-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
-
-
- -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- booleangetRandomBoolean() - -
-          Returns a random boolean.
- java.lang.StringgetRandomFilename(java.lang.String extension) - -
-          Returns an unguessable random filename with the specified extension.
- java.lang.StringgetRandomGUID() - -
-          Generates a random GUID.
- intgetRandomInteger(int min, - int max) - -
-          Gets the random integer.
- floatgetRandomReal(float min, - float max) - -
-          Gets the random real.
- java.lang.StringgetRandomString(int length, - char[] characterSet) - -
-          Gets the random string.
-  -

- - - - - - - - - - - - - - -
-Method Detail
- -

-getRandomString

-
-public java.lang.String getRandomString(int length,
-                                        char[] characterSet)
-
-
Gets the random string. -

-

-
Parameters:
length - the length
characterSet - the character set -
Returns:
the random string
-
-
-
- -

-getRandomBoolean

-
-public boolean getRandomBoolean()
-
-
Returns a random boolean. -

-

- -
Returns:
-
-
-
- -

-getRandomInteger

-
-public int getRandomInteger(int min,
-                            int max)
-
-
Gets the random integer. -

-

-
Parameters:
min - the min
max - the max -
Returns:
the random integer
-
-
-
- -

-getRandomFilename

-
-public java.lang.String getRandomFilename(java.lang.String extension)
-
-
Returns an unguessable random filename with the specified extension. -

-

-
-
-
-
- -

-getRandomReal

-
-public float getRandomReal(float min,
-                           float max)
-
-
Gets the random real. -

-

-
Parameters:
min - the min
max - the max -
Returns:
the random real
-
-
-
- -

-getRandomGUID

-
-public java.lang.String getRandomGUID()
-                               throws EncryptionException
-
-
Generates a random GUID. -

-

- -
Returns:
the GUID -
Throws: -
EncryptionException
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/ISecurityConfiguration.html b/javadoc/org/owasp/esapi/interfaces/ISecurityConfiguration.html deleted file mode 100644 index 116dbc1d7..000000000 --- a/javadoc/org/owasp/esapi/interfaces/ISecurityConfiguration.html +++ /dev/null @@ -1,612 +0,0 @@ - - - - - - -ISecurityConfiguration - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.interfaces -
-Interface ISecurityConfiguration

-
-
All Known Implementing Classes:
SecurityConfiguration
-
-
-
-
public interface ISecurityConfiguration
- -

-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
-
-
- -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- java.util.ListgetAllowedFileExtensions() - -
-          Gets the allowed file extensions.
- intgetAllowedFileUploadSize() - -
-          Gets the allowed file upload size.
- intgetAllowedLoginAttempts() - -
-          Gets the allowed login attempts.
- java.lang.StringgetApplicationName() - -
-          Gets the application name, used for logging
- java.lang.StringgetCharacterEncoding() - -
-          Gets the character encoding.
- java.lang.StringgetDigitalSignatureAlgorithm() - -
-          Gets the digital signature algorithm.
- java.lang.StringgetEncryptionAlgorithm() - -
-          Gets the encryption algorithm.
- java.lang.StringgetHashAlgorithm() - -
-          Gets the hasing algorithm.
- java.io.FilegetKeystore() - -
-          Gets the keystore.
- char[]getMasterPassword() - -
-          Gets the master password.
- byte[]getMasterSalt() - -
-          Gets the master salt.
- intgetMaxOldPasswordHashes() - -
-          Gets the max old password hashes.
- java.lang.StringgetPasswordParameterName() - -
-          Gets the password parameter name.
- ThresholdgetQuota(java.lang.String eventName) - -
-          Gets an intrusion detection Quota.
- java.lang.StringgetRandomAlgorithm() - -
-          Gets the random number generation algorithm.
- java.lang.StringgetResourceDirectory() - -
-          Gets the ESAPI resource directory as a String.
- java.lang.StringgetUsernameParameterName() - -
-          Gets the username parameter name.
- voidsetResourceDirectory(java.lang.String dir) - -
-          Sets the ESAPI resource directory.
-  -

- - - - - - - - - - - - - - -
-Method Detail
- -

-getApplicationName

-
-public java.lang.String getApplicationName()
-
-
Gets the application name, used for logging -

-

- -
Returns:
the application name
-
-
-
- -

-getMasterPassword

-
-public char[] getMasterPassword()
-
-
Gets the master password. -

-

- -
Returns:
the master password
-
-
-
- -

-getKeystore

-
-public java.io.File getKeystore()
-
-
Gets the keystore. -

-

- -
Returns:
the keystore
-
-
-
- -

-getMasterSalt

-
-public byte[] getMasterSalt()
-
-
Gets the master salt. -

-

- -
Returns:
the master salt
-
-
-
- -

-getAllowedFileExtensions

-
-public java.util.List getAllowedFileExtensions()
-
-
Gets the allowed file extensions. -

-

- -
Returns:
the allowed file extensions
-
-
-
- -

-getAllowedFileUploadSize

-
-public int getAllowedFileUploadSize()
-
-
Gets the allowed file upload size. -

-

- -
Returns:
the allowed file upload size
-
-
-
- -

-getPasswordParameterName

-
-public java.lang.String getPasswordParameterName()
-
-
Gets the password parameter name. -

-

- -
Returns:
the password parameter name
-
-
-
- -

-getUsernameParameterName

-
-public java.lang.String getUsernameParameterName()
-
-
Gets the username parameter name. -

-

- -
Returns:
the username parameter name
-
-
-
- -

-getEncryptionAlgorithm

-
-public java.lang.String getEncryptionAlgorithm()
-
-
Gets the encryption algorithm. -

-

- -
Returns:
the algorithm
-
-
-
- -

-getHashAlgorithm

-
-public java.lang.String getHashAlgorithm()
-
-
Gets the hasing algorithm. -

-

- -
Returns:
the algorithm
-
-
-
- -

-getCharacterEncoding

-
-public java.lang.String getCharacterEncoding()
-
-
Gets the character encoding. -

-

- -
Returns:
encoding name
-
-
-
- -

-getDigitalSignatureAlgorithm

-
-public java.lang.String getDigitalSignatureAlgorithm()
-
-
Gets the digital signature algorithm. -

-

- -
Returns:
encoding name
-
-
-
- -

-getRandomAlgorithm

-
-public java.lang.String getRandomAlgorithm()
-
-
Gets the random number generation algorithm. -

-

- -
Returns:
encoding name
-
-
-
- -

-getAllowedLoginAttempts

-
-public int getAllowedLoginAttempts()
-
-
Gets the allowed login attempts. -

-

- -
Returns:
the allowed login attempts
-
-
-
- -

-getMaxOldPasswordHashes

-
-public int getMaxOldPasswordHashes()
-
-
Gets the max old password hashes. -

-

- -
Returns:
the max old password hashes
-
-
-
- -

-getQuota

-
-public Threshold getQuota(java.lang.String eventName)
-
-
Gets an intrusion detection Quota. -

-

-
Parameters:
eventName - -
Returns:
the matching Quota
-
-
-
- -

-getResourceDirectory

-
-public java.lang.String getResourceDirectory()
-
-
Gets the ESAPI resource directory as a String. -

-

-
-
-
-
- -

-setResourceDirectory

-
-public void setResourceDirectory(java.lang.String dir)
-
-
Sets the ESAPI resource directory. -

-

-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/IUser.html b/javadoc/org/owasp/esapi/interfaces/IUser.html deleted file mode 100644 index b9facb1b1..000000000 --- a/javadoc/org/owasp/esapi/interfaces/IUser.html +++ /dev/null @@ -1,1036 +0,0 @@ - - - - - - -IUser - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.interfaces -
-Interface IUser

-
-
All Known Implementing Classes:
User
-
-
-
-
public interface IUser
- -

-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. -

- -

-

-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams at Aspect Security
-
-
- -

- - - - - - - - - - - - - - -
-Field Summary
-static IUserANONYMOUS - -
-           
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- voidaddRole(java.lang.String role) - -
-          Adds a role to an account.
- voidaddRoles(java.util.Set newRoles) - -
-          Adds the roles.
- voidchangePassword(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.
- voiddisable() - -
-          Disable account.
- voidenable() - -
-          Enable account.
- java.lang.StringgetAccountName() - -
-          Gets the account name.
- java.lang.StringgetCSRFToken() - -
-          Gets the CSRF token.
- intgetFailedLoginCount() - -
-          Returns the number of failed login attempts since the last successful login for an account.
- java.util.DategetLastFailedLoginTime() - -
-          Returns the date of the last failed login time for a user.
- java.lang.StringgetLastHostAddress() - -
-          Returns the last host address used by the user.
- java.util.DategetLastLoginTime() - -
-          Returns the date of the last successful login time for a user.
- java.util.DategetLastPasswordChangeTime() - -
-          Gets the last password change time.
- java.util.SetgetRoles() - -
-          Gets the roles assigned to a particular account.
- java.lang.StringgetScreenName() - -
-          Gets the screen name.
- voidincrementFailedLoginCount() - -
-          Increment failed login count.
- booleanisAnonymous() - -
-          Checks if is anonymous.
- booleanisEnabled() - -
-          Checks if an account is currently enabled.
- booleanisExpired() - -
-          Checks if an account is expired.
- booleanisInRole(java.lang.String role) - -
-          Checks if an account has been assigned a particular role.
- booleanisLocked() - -
-          Checks if an account is unlocked.
- booleanisLoggedIn() - -
-          Tests to see if the user is currently logged in.
- booleanisSessionAbsoluteTimeout() - -
-          Tests to see if the user's session has exceeded the absolute time out.
- booleanisSessionTimeout() - -
-          Tests to see if the user's session has timed out from inactivity.
- voidlock() - -
-          Lock the user's account.
- voidloginWithPassword(java.lang.String password) - -
-          Login with password.
- voidlogout() - -
-          Logout this user.
- voidremoveRole(java.lang.String role) - -
-          Removes a role from an account.
- java.lang.StringresetCSRFToken() - -
-          Returns a token to be used as a prevention against CSRF attacks.
- java.lang.StringresetRememberToken() - -
-          Returns a token to be used as a "remember me" cookie.
- voidsetAccountName(java.lang.String accountName) - -
-          Sets the account name.
- voidsetRoles(java.util.Set roles) - -
-          Sets the roles.
- voidsetScreenName(java.lang.String screenName) - -
-          Sets the screen name.
- voidunlock() - -
-          Unlock account.
- booleanverifyPassword(java.lang.String password) - -
-          Verify that the supplied password matches the password for this user.
-  -

- - - - - - - - -
-Field Detail
- -

-ANONYMOUS

-
-public static final IUser ANONYMOUS
-
-
-
-
- - - - - - - - - - - -
-Method Detail
- -

-addRole

-
-public void addRole(java.lang.String role)
-             throws AuthenticationException
-
-
Adds a role to an account. -

-

-
Parameters:
role - the role -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-addRoles

-
-public void addRoles(java.util.Set newRoles)
-              throws AuthenticationException
-
-
Adds the roles. -

-

-
Parameters:
newRoles - the new roles -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-changePassword

-
-public void changePassword(java.lang.String oldPassword,
-                           java.lang.String newPassword1,
-                           java.lang.String newPassword2)
-                    throws AuthenticationException,
-                           EncryptionException
-
-
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 password1
newPassword2 - the new password2 -
Throws: -
AuthenticationException - the authentication exception -
EncryptionException
-
-
-
- -

-disable

-
-public void disable()
-
-
Disable account. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-enable

-
-public void enable()
-
-
Enable account. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-getAccountName

-
-public java.lang.String getAccountName()
-
-
Gets the account name. -

-

- -
Returns:
the account name
-
-
-
- -

-getCSRFToken

-
-public java.lang.String getCSRFToken()
-
-
Gets the CSRF token. -

-

- -
Returns:
the CSRF token
-
-
-
- -

-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:
-
-
-
- -

-getLastFailedLoginTime

-
-public java.util.Date getLastFailedLoginTime()
-                                      throws AuthenticationException
-
-
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:
date of the last failed login -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-getLastLoginTime

-
-public java.util.Date getLastLoginTime()
-
-
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:
date of the last successful login
-
-
-
- -

-getLastPasswordChangeTime

-
-public java.util.Date getLastPasswordChangeTime()
-
-
Gets the last password change time. -

-

- -
Returns:
the last password change time
-
-
-
- -

-getRoles

-
-public java.util.Set getRoles()
-
-
Gets the roles assigned to a particular account. -

-

- -
Returns:
an immutable set of roles
-
-
-
- -

-getScreenName

-
-public java.lang.String getScreenName()
-
-
Gets the screen name. -

-

- -
Returns:
the screen name
-
-
-
- -

-incrementFailedLoginCount

-
-public void incrementFailedLoginCount()
-
-
Increment failed login count. -

-

-
-
-
-
- -

-isAnonymous

-
-public boolean isAnonymous()
-
-
Checks if is anonymous. -

-

- -
Returns:
true, if is anonymous
-
-
-
- -

-isEnabled

-
-public boolean isEnabled()
-
-
Checks if an account is currently enabled. -

-

- -
Returns:
true, if is enabled account
-
-
-
- -

-isExpired

-
-public boolean isExpired()
-
-
Checks if an account is expired. -

-

- -
Returns:
true, account is expired
-
-
-
- -

-isInRole

-
-public boolean isInRole(java.lang.String role)
-
-
Checks if an account has been assigned a particular role. -

-

-
Parameters:
role - the role -
Returns:
true, if is user in role
-
-
-
- -

-isLocked

-
-public boolean isLocked()
-
-
Checks if an account is unlocked. -

-

- -
Returns:
true, account is unlocked
-
-
-
- -

-isLoggedIn

-
-public boolean isLoggedIn()
-
-
Tests to see if the user is currently logged in. -

-

- -
Returns:
true if the user is logged out
-
-
-
- -

-isSessionAbsoluteTimeout

-
-public boolean isSessionAbsoluteTimeout()
-
-
Tests to see if the user's session has exceeded the absolute time out. -

-

- -
Returns:
whether user's session has exceeded the absolute time out
-
-
-
- -

-isSessionTimeout

-
-public boolean isSessionTimeout()
-
-
Tests to see if the user's session has timed out from inactivity. -

-

- -
Returns:
whether user's session has timed out from inactivity
-
-
-
- -

-lock

-
-public void lock()
-
-
Lock the user's account. -

-

-
-
-
-
- -

-loginWithPassword

-
-public void loginWithPassword(java.lang.String password)
-                       throws AuthenticationException
-
-
Login with password. -

-

-
Parameters:
password - the password -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-logout

-
-public void logout()
-
-
Logout this user. -

-

-
-
-
-
- -

-removeRole

-
-public void removeRole(java.lang.String role)
-                throws AuthenticationException
-
-
Removes a role from an account. -

-

-
Parameters:
role - the role -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-resetCSRFToken

-
-public java.lang.String resetCSRFToken()
-                                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. -

-

- -
Returns:
the string -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-resetRememberToken

-
-public java.lang.String resetRememberToken()
-                                    throws AuthenticationException
-
-
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. -

-

- -
Returns:
the string -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-setAccountName

-
-public void setAccountName(java.lang.String accountName)
-
-
Sets the account name. -

-

-
Parameters:
accountName - the new account name
-
-
-
- -

-setRoles

-
-public void setRoles(java.util.Set roles)
-              throws AuthenticationException
-
-
Sets the roles. -

-

-
Parameters:
roles - the new roles -
Throws: -
AuthenticationException
-
-
-
- -

-setScreenName

-
-public void setScreenName(java.lang.String screenName)
-
-
Sets the screen name. -

-

-
Parameters:
screenName - the new screen name
-
-
-
- -

-unlock

-
-public void unlock()
-
-
Unlock account. -

-

-
-
-
-
- -

-verifyPassword

-
-public boolean verifyPassword(java.lang.String password)
-                       throws EncryptionException
-
-
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 - -
Returns:
-
Throws: -
EncryptionException
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/IValidator.html b/javadoc/org/owasp/esapi/interfaces/IValidator.html deleted file mode 100644 index ea98de99b..000000000 --- a/javadoc/org/owasp/esapi/interfaces/IValidator.html +++ /dev/null @@ -1,1322 +0,0 @@ - - - - - - -IValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.interfaces -
-Interface IValidator

-
-
All Known Implementing Classes:
Validator
-
-
-
-
public interface IValidator
- -

-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
- voidassertIsValidHTTPRequest() - -
-          Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed - characters.
- voidassertIsValidHTTPRequestParameterSet(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.
- voidassertValidFileUpload(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.StringgetValidCreditCard(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated credit card number as a String.
- java.util.DategetValidDate(java.lang.String context, - java.lang.String input, - java.text.DateFormat format, - boolean allowNull) - -
-          Returns a valid date as a Date.
- java.lang.StringgetValidDirectoryPath(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated directory path as a String.
- java.lang.DoublegetValidDouble(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.StringgetValidFileName(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated file name as a String.
- java.lang.StringgetValidInput(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.IntegergetValidInteger(java.lang.String context, - java.lang.String input, - int minValue, - int maxValue, - boolean allowNull) - -
-          Returns a validated integer as an int.
- java.lang.StringgetValidListItem(java.lang.String context, - java.lang.String input, - java.util.List list) - -
-          Returns the list item that exactly matches the canonicalized input.
- java.lang.DoublegetValidNumber(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.StringgetValidPrintable(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-          Returns canonicalized and validated printable characters as a String.
- java.lang.StringgetValidRedirectLocation(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated redirect location as a String.
- java.lang.StringgetValidSafeHTML(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-          Returns canonicalized and validated "safe" HTML.
- booleanisValidCreditCard(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns true if input is a valid credit card.
- booleanisValidDate(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.
- booleanisValidDirectoryPath(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns true if input is a valid directory path.
- booleanisValidDouble(java.lang.String context, - java.lang.String input, - double minValue, - double maxValue, - boolean allowNull) - -
-          Returns true if input is a valid double.
- booleanisValidFileContent(java.lang.String context, - byte[] input, - int maxBytes, - boolean allowNull) - -
-          Returns true if input is valid file content.
- booleanisValidFileName(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns true if input is a valid file name.
- booleanisValidFileUpload(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.
- booleanisValidHTTPRequest() - -
-          Validate the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed - characters.
- booleanisValidHTTPRequestParameterSet(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.
- booleanisValidInput(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.
- booleanisValidInteger(java.lang.String context, - java.lang.String input, - int minValue, - int maxValue, - boolean allowNull) - -
-          Returns true if input is a valid integer.
- booleanisValidListItem(java.lang.String context, - java.lang.String input, - java.util.List list) - -
-          Returns true if input is a valid list item.
- booleanisValidNumber(java.lang.String context, - java.lang.String input, - long minValue, - long maxValue, - boolean allowNull) - -
-          Returns true if input is a valid number.
- booleanisValidPrintable(java.lang.String context, - byte[] input, - int maxLength, - boolean allowNull) - -
-          Returns true if input is valid printable ASCII characters.
- booleanisValidPrintable(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-          Returns true if input is valid printable ASCII characters (32-126).
- booleanisValidRedirectLocation(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns true if input is a valid redirect location.
- booleanisValidSafeHTML(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-          Returns true if input is "safe" HTML.
- java.lang.StringsafeReadLine(java.io.InputStream inputStream, - int maxLength) - -
-          Reads from an input stream until end-of-line or a maximum number of - characters.
-  -

- - - - - - - - - - - - - - -
-Method Detail
- -

-isValidInput

-
-public boolean isValidInput(java.lang.String context,
-                            java.lang.String input,
-                            java.lang.String type,
-                            int maxLength,
-                            boolean allowNull)
-                     throws IntrusionException
-
-
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:
The canonicalized user input. -
Throws: -
IntrusionException
-
-
-
- -

-getValidInput

-
-public java.lang.String getValidInput(java.lang.String context,
-                                      java.lang.String input,
-                                      java.lang.String type,
-                                      int maxLength,
-                                      boolean allowNull)
-                               throws ValidationException,
-                                      IntrusionException
-
-
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:
The canonicalized user input. -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-isValidDate

-
-public boolean isValidDate(java.lang.String context,
-                           java.lang.String input,
-                           java.text.DateFormat format,
-                           boolean allowNull)
-                    throws IntrusionException
-
-
Returns true if input is a valid date according to the specified date format. -

-

- -
Throws: -
IntrusionException
-
-
-
- -

-getValidDate

-
-public java.util.Date getValidDate(java.lang.String context,
-                                   java.lang.String input,
-                                   java.text.DateFormat format,
-                                   boolean allowNull)
-                            throws ValidationException,
-                                   IntrusionException
-
-
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. -

-

- -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-isValidSafeHTML

-
-public boolean isValidSafeHTML(java.lang.String context,
-                               java.lang.String input,
-                               int maxLength,
-                               boolean allowNull)
-                        throws 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. -

-

- -
Throws: -
IntrusionException
-
-
-
- -

-getValidSafeHTML

-
-public java.lang.String getValidSafeHTML(java.lang.String context,
-                                         java.lang.String input,
-                                         int maxLength,
-                                         boolean allowNull)
-                                  throws 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. -

-

- -
Throws: -
ValidationException
-
-
-
- -

-isValidCreditCard

-
-public boolean isValidCreditCard(java.lang.String context,
-                                 java.lang.String input,
-                                 boolean allowNull)
-                          throws IntrusionException
-
-
Returns true if input is a valid credit card. Maxlength is mandated by valid credit card type. -

-

- -
Throws: -
IntrusionException
-
-
-
- -

-getValidCreditCard

-
-public java.lang.String getValidCreditCard(java.lang.String context,
-                                           java.lang.String input,
-                                           boolean allowNull)
-                                    throws ValidationException,
-                                           IntrusionException
-
-
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. -

-

- -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-isValidDirectoryPath

-
-public boolean isValidDirectoryPath(java.lang.String context,
-                                    java.lang.String input,
-                                    boolean allowNull)
-                             throws IntrusionException
-
-
Returns true if input is a valid directory path. -

-

- -
Throws: -
IntrusionException
-
-
-
- -

-getValidDirectoryPath

-
-public java.lang.String getValidDirectoryPath(java.lang.String context,
-                                              java.lang.String input,
-                                              boolean allowNull)
-                                       throws ValidationException,
-                                              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. -

-

- -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-isValidFileName

-
-public boolean isValidFileName(java.lang.String context,
-                               java.lang.String input,
-                               boolean allowNull)
-                        throws IntrusionException
-
-
Returns true if input is a valid file name. -

-

- -
Throws: -
IntrusionException
-
-
-
- -

-getValidFileName

-
-public java.lang.String getValidFileName(java.lang.String context,
-                                         java.lang.String input,
-                                         boolean allowNull)
-                                  throws ValidationException,
-                                         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. -

-

- -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-isValidNumber

-
-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. -

-

- -
Throws: -
IntrusionException
-
-
-
- -

-getValidNumber

-
-public java.lang.Double getValidNumber(java.lang.String context,
-                                       java.lang.String input,
-                                       long minValue,
-                                       long maxValue,
-                                       boolean allowNull)
-                                throws ValidationException,
-                                       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. -

-

- -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-isValidInteger

-
-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. -

-

- -
Throws: -
IntrusionException
-
-
-
- -

-getValidInteger

-
-public java.lang.Integer getValidInteger(java.lang.String context,
-                                         java.lang.String input,
-                                         int minValue,
-                                         int maxValue,
-                                         boolean allowNull)
-                                  throws ValidationException,
-                                         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. -

-

- -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-isValidDouble

-
-public boolean isValidDouble(java.lang.String context,
-                             java.lang.String input,
-                             double minValue,
-                             double maxValue,
-                             boolean allowNull)
-                      throws IntrusionException
-
-
Returns true if input is a valid double. -

-

- -
Throws: -
IntrusionException
-
-
-
- -

-getValidDouble

-
-public java.lang.Double getValidDouble(java.lang.String context,
-                                       java.lang.String input,
-                                       double minValue,
-                                       double maxValue,
-                                       boolean allowNull)
-                                throws ValidationException,
-                                       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. -

-

- -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-isValidFileContent

-
-public boolean isValidFileContent(java.lang.String context,
-                                  byte[] input,
-                                  int maxBytes,
-                                  boolean allowNull)
-                           throws IntrusionException
-
-
Returns true if input is valid file content. -

-

- -
Throws: -
IntrusionException
-
-
-
- -

-getValidFileContent

-
-public byte[] getValidFileContent(java.lang.String context,
-                                  byte[] input,
-                                  int maxBytes,
-                                  boolean allowNull)
-                           throws ValidationException,
-                                  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. -

-

- -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-isValidFileUpload

-
-public boolean isValidFileUpload(java.lang.String context,
-                                 java.lang.String filepath,
-                                 java.lang.String filename,
-                                 byte[] content,
-                                 int maxBytes,
-                                 boolean allowNull)
-                          throws IntrusionException
-
-
Returns true if a file upload has a valid name, path, and content. -

-

- -
Throws: -
IntrusionException
-
-
-
- -

-assertValidFileUpload

-
-public void assertValidFileUpload(java.lang.String context,
-                                  java.lang.String filepath,
-                                  java.lang.String filename,
-                                  byte[] content,
-                                  int maxBytes,
-                                  boolean allowNull)
-                           throws ValidationException,
-                                  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. -

-

- -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-isValidHTTPRequest

-
-public boolean isValidHTTPRequest()
-                           throws 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. -

-

- -
Throws: -
IntrusionException
-
-
-
- -

-assertIsValidHTTPRequest

-
-public void assertIsValidHTTPRequest()
-                              throws ValidationException,
-                                     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. -

-

- -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-isValidListItem

-
-public boolean isValidListItem(java.lang.String context,
-                               java.lang.String input,
-                               java.util.List list)
-                        throws IntrusionException
-
-
Returns true if input is a valid list item. -

-

- -
Throws: -
IntrusionException
-
-
-
- -

-getValidListItem

-
-public java.lang.String getValidListItem(java.lang.String context,
-                                         java.lang.String input,
-                                         java.util.List list)
-                                  throws ValidationException,
-                                         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. -

-

- -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-isValidHTTPRequestParameterSet

-
-public boolean isValidHTTPRequestParameterSet(java.lang.String context,
-                                              java.util.Set required,
-                                              java.util.Set optional)
-                                       throws IntrusionException
-
-
Returns true if the parameters in the current request contain all required parameters and only optional ones in addition. -

-

- -
Throws: -
IntrusionException
-
-
-
- -

-assertIsValidHTTPRequestParameterSet

-
-public void assertIsValidHTTPRequestParameterSet(java.lang.String context,
-                                                 java.util.Set required,
-                                                 java.util.Set optional)
-                                          throws ValidationException,
-                                                 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. -

-

- -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-isValidPrintable

-
-public boolean isValidPrintable(java.lang.String context,
-                                byte[] input,
-                                int maxLength,
-                                boolean allowNull)
-                         throws IntrusionException
-
-
Returns true if input is valid printable ASCII characters. -

-

- -
Throws: -
IntrusionException
-
-
-
- -

-getValidPrintable

-
-public byte[] getValidPrintable(java.lang.String context,
-                                byte[] input,
-                                int maxLength,
-                                boolean allowNull)
-                         throws ValidationException
-
-
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. -

-

- -
Throws: -
ValidationException
-
-
-
- -

-isValidPrintable

-
-public boolean isValidPrintable(java.lang.String context,
-                                java.lang.String input,
-                                int maxLength,
-                                boolean allowNull)
-                         throws IntrusionException
-
-
Returns true if input is valid printable ASCII characters (32-126). -

-

- -
Throws: -
IntrusionException
-
-
-
- -

-getValidPrintable

-
-public java.lang.String getValidPrintable(java.lang.String context,
-                                          java.lang.String input,
-                                          int maxLength,
-                                          boolean allowNull)
-                                   throws ValidationException
-
-
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. -

-

- -
Throws: -
ValidationException
-
-
-
- -

-isValidRedirectLocation

-
-public boolean isValidRedirectLocation(java.lang.String context,
-                                       java.lang.String input,
-                                       boolean allowNull)
-                                throws IntrusionException
-
-
Returns true if input is a valid redirect location. -

-

- -
Throws: -
IntrusionException
-
-
-
- -

-getValidRedirectLocation

-
-public java.lang.String getValidRedirectLocation(java.lang.String context,
-                                                 java.lang.String input,
-                                                 boolean allowNull)
-                                          throws ValidationException
-
-
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. -

-

- -
Throws: -
ValidationException
-
-
-
- -

-safeReadLine

-
-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. -

-

- -
Throws: -
ValidationException
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/class-use/IAccessController.html b/javadoc/org/owasp/esapi/interfaces/class-use/IAccessController.html deleted file mode 100644 index d3412c569..000000000 --- a/javadoc/org/owasp/esapi/interfaces/class-use/IAccessController.html +++ /dev/null @@ -1,204 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.interfaces.IAccessController - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.interfaces.IAccessController

-
- - - - - - - - - -
-Packages that use IAccessController
org.owasp.esapiReference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of IAccessController in org.owasp.esapi
-  -

- - - - - - - - - -
Classes in org.owasp.esapi that implement IAccessController
- classAccessController - -
-          Reference implementation of the IAccessController interface.
-  -

- - - - - - - - - -
Methods in org.owasp.esapi that return IAccessController
-static IAccessControllerESAPI.accessController() - -
-           
-  -

- - - - - - - - - -
Methods in org.owasp.esapi with parameters of type IAccessController
-static voidESAPI.setAccessController(IAccessController accessController) - -
-           
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/class-use/IAccessReferenceMap.html b/javadoc/org/owasp/esapi/interfaces/class-use/IAccessReferenceMap.html deleted file mode 100644 index e61bb7fc9..000000000 --- a/javadoc/org/owasp/esapi/interfaces/class-use/IAccessReferenceMap.html +++ /dev/null @@ -1,172 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.interfaces.IAccessReferenceMap - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.interfaces.IAccessReferenceMap

-
- - - - - - - - - -
-Packages that use IAccessReferenceMap
org.owasp.esapiReference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of IAccessReferenceMap in org.owasp.esapi
-  -

- - - - - - - - - -
Classes in org.owasp.esapi that implement IAccessReferenceMap
- classAccessReferenceMap - -
-          Reference implementation of the IAccessReferenceMap interface.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/class-use/IAuthenticator.html b/javadoc/org/owasp/esapi/interfaces/class-use/IAuthenticator.html deleted file mode 100644 index 36ea49a21..000000000 --- a/javadoc/org/owasp/esapi/interfaces/class-use/IAuthenticator.html +++ /dev/null @@ -1,204 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.interfaces.IAuthenticator - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.interfaces.IAuthenticator

-
- - - - - - - - - -
-Packages that use IAuthenticator
org.owasp.esapiReference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of IAuthenticator in org.owasp.esapi
-  -

- - - - - - - - - -
Classes in org.owasp.esapi that implement IAuthenticator
- classAuthenticator - -
-          Reference implementation of the IAuthenticator interface.
-  -

- - - - - - - - - -
Methods in org.owasp.esapi that return IAuthenticator
-static IAuthenticatorESAPI.authenticator() - -
-           
-  -

- - - - - - - - - -
Methods in org.owasp.esapi with parameters of type IAuthenticator
-static voidESAPI.setAuthenticator(IAuthenticator authenticator) - -
-           
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/class-use/IEncoder.html b/javadoc/org/owasp/esapi/interfaces/class-use/IEncoder.html deleted file mode 100644 index 02f61e116..000000000 --- a/javadoc/org/owasp/esapi/interfaces/class-use/IEncoder.html +++ /dev/null @@ -1,204 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.interfaces.IEncoder - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.interfaces.IEncoder

-
- - - - - - - - - -
-Packages that use IEncoder
org.owasp.esapiReference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of IEncoder in org.owasp.esapi
-  -

- - - - - - - - - -
Classes in org.owasp.esapi that implement IEncoder
- classEncoder - -
-          Reference implementation of the IEncoder interface.
-  -

- - - - - - - - - -
Methods in org.owasp.esapi that return IEncoder
-static IEncoderESAPI.encoder() - -
-           
-  -

- - - - - - - - - -
Methods in org.owasp.esapi with parameters of type IEncoder
-static voidESAPI.setEncoder(IEncoder encoder) - -
-           
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/class-use/IEncryptedProperties.html b/javadoc/org/owasp/esapi/interfaces/class-use/IEncryptedProperties.html deleted file mode 100644 index 3a22d48c4..000000000 --- a/javadoc/org/owasp/esapi/interfaces/class-use/IEncryptedProperties.html +++ /dev/null @@ -1,172 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.interfaces.IEncryptedProperties - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.interfaces.IEncryptedProperties

-
- - - - - - - - - -
-Packages that use IEncryptedProperties
org.owasp.esapiReference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of IEncryptedProperties in org.owasp.esapi
-  -

- - - - - - - - - -
Classes in org.owasp.esapi that implement IEncryptedProperties
- classEncryptedProperties - -
-          Reference implementation of the IEncryptedProperties interface.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/class-use/IEncryptor.html b/javadoc/org/owasp/esapi/interfaces/class-use/IEncryptor.html deleted file mode 100644 index ee9e7f9d1..000000000 --- a/javadoc/org/owasp/esapi/interfaces/class-use/IEncryptor.html +++ /dev/null @@ -1,204 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.interfaces.IEncryptor - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.interfaces.IEncryptor

-
- - - - - - - - - -
-Packages that use IEncryptor
org.owasp.esapiReference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of IEncryptor in org.owasp.esapi
-  -

- - - - - - - - - -
Classes in org.owasp.esapi that implement IEncryptor
- classEncryptor - -
-          Reference implementation of the IEncryptor interface.
-  -

- - - - - - - - - -
Methods in org.owasp.esapi that return IEncryptor
-static IEncryptorESAPI.encryptor() - -
-           
-  -

- - - - - - - - - -
Methods in org.owasp.esapi with parameters of type IEncryptor
-static voidESAPI.setEncryptor(IEncryptor encryptor) - -
-           
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/class-use/IExecutor.html b/javadoc/org/owasp/esapi/interfaces/class-use/IExecutor.html deleted file mode 100644 index c00cc8ba5..000000000 --- a/javadoc/org/owasp/esapi/interfaces/class-use/IExecutor.html +++ /dev/null @@ -1,204 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.interfaces.IExecutor - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.interfaces.IExecutor

-
- - - - - - - - - -
-Packages that use IExecutor
org.owasp.esapiReference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of IExecutor in org.owasp.esapi
-  -

- - - - - - - - - -
Classes in org.owasp.esapi that implement IExecutor
- classExecutor - -
-          Reference implementation of the Executor interface.
-  -

- - - - - - - - - -
Methods in org.owasp.esapi that return IExecutor
-static IExecutorESAPI.executor() - -
-           
-  -

- - - - - - - - - -
Methods in org.owasp.esapi with parameters of type IExecutor
-static voidESAPI.setExecutor(IExecutor executor) - -
-           
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/class-use/IHTTPUtilities.html b/javadoc/org/owasp/esapi/interfaces/class-use/IHTTPUtilities.html deleted file mode 100644 index ac291abe2..000000000 --- a/javadoc/org/owasp/esapi/interfaces/class-use/IHTTPUtilities.html +++ /dev/null @@ -1,204 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.interfaces.IHTTPUtilities - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.interfaces.IHTTPUtilities

-
- - - - - - - - - -
-Packages that use IHTTPUtilities
org.owasp.esapiReference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of IHTTPUtilities in org.owasp.esapi
-  -

- - - - - - - - - -
Classes in org.owasp.esapi that implement IHTTPUtilities
- classHTTPUtilities - -
-          Reference implementation of the IHTTPUtilities interface.
-  -

- - - - - - - - - -
Methods in org.owasp.esapi that return IHTTPUtilities
-static IHTTPUtilitiesESAPI.httpUtilities() - -
-           
-  -

- - - - - - - - - -
Methods in org.owasp.esapi with parameters of type IHTTPUtilities
-static voidESAPI.setHttpUtilities(IHTTPUtilities httpUtilities) - -
-           
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/class-use/IIntrusionDetector.html b/javadoc/org/owasp/esapi/interfaces/class-use/IIntrusionDetector.html deleted file mode 100644 index 6d2a294e3..000000000 --- a/javadoc/org/owasp/esapi/interfaces/class-use/IIntrusionDetector.html +++ /dev/null @@ -1,204 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.interfaces.IIntrusionDetector - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.interfaces.IIntrusionDetector

-
- - - - - - - - - -
-Packages that use IIntrusionDetector
org.owasp.esapiReference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of IIntrusionDetector in org.owasp.esapi
-  -

- - - - - - - - - -
Classes in org.owasp.esapi that implement IIntrusionDetector
- classIntrusionDetector - -
-          Reference implementation of the IIntrusionDetector interface.
-  -

- - - - - - - - - -
Methods in org.owasp.esapi that return IIntrusionDetector
-static IIntrusionDetectorESAPI.intrusionDetector() - -
-           
-  -

- - - - - - - - - -
Methods in org.owasp.esapi with parameters of type IIntrusionDetector
-static voidESAPI.setIntrusionDetector(IIntrusionDetector intrusionDetector) - -
-           
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/class-use/ILogFactory.html b/javadoc/org/owasp/esapi/interfaces/class-use/ILogFactory.html deleted file mode 100644 index f7f92c38c..000000000 --- a/javadoc/org/owasp/esapi/interfaces/class-use/ILogFactory.html +++ /dev/null @@ -1,188 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.interfaces.ILogFactory - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.interfaces.ILogFactory

-
- - - - - - - - - -
-Packages that use ILogFactory
org.owasp.esapiReference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of ILogFactory in org.owasp.esapi
-  -

- - - - - - - - - -
Classes in org.owasp.esapi that implement ILogFactory
- classJavaLogFactory - -
-           
-  -

- - - - - - - - - -
Methods in org.owasp.esapi with parameters of type ILogFactory
-static voidESAPI.setLogger(ILogFactory factory) - -
-           
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/class-use/ILogger.html b/javadoc/org/owasp/esapi/interfaces/class-use/ILogger.html deleted file mode 100644 index 0a7bca78f..000000000 --- a/javadoc/org/owasp/esapi/interfaces/class-use/ILogger.html +++ /dev/null @@ -1,310 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.interfaces.ILogger - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.interfaces.ILogger

-
- - - - - - - - - - - - - -
-Packages that use ILogger
org.owasp.esapiReference implementations of the ESAPI interfaces. 
org.owasp.esapi.interfacesA set of interfaces modeling the most important security functions to -enterprise web applications. 
-  -

- - - - - -
-Uses of ILogger in org.owasp.esapi
-  -

- - - - - - - - - -
Classes in org.owasp.esapi that implement ILogger
- classLogger - -
-          Reference implementation of the ILogger interface.
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi that return ILogger
- ILoggerJavaLogFactory.getLogger(java.lang.Class clazz) - -
-           
- ILoggerJavaLogFactory.getLogger(java.lang.String name) - -
-           
-static ILoggerESAPI.getLogger(java.lang.Class clazz) - -
-           
-static ILoggerESAPI.getLogger(java.lang.String name) - -
-           
-static ILoggerESAPI.log() - -
-           
-  -

- - - - - - - - - - - - - -
Methods in org.owasp.esapi with parameters of type ILogger
- voidHTTPUtilities.logHTTPRequest(ILogger logger) - -
-           
- voidHTTPUtilities.logHTTPRequest(ILogger logger, - java.util.List parameterNamesToObfuscate) - -
-          Formats an HTTP request into a log suitable string.
-  -

- - - - - -
-Uses of ILogger in org.owasp.esapi.interfaces
-  -

- - - - - - - - - - - - - -
Methods in org.owasp.esapi.interfaces that return ILogger
- ILoggerILogFactory.getLogger(java.lang.String name) - -
-           
- ILoggerILogFactory.getLogger(java.lang.Class clazz) - -
-           
-  -

- - - - - - - - - - - - - -
Methods in org.owasp.esapi.interfaces with parameters of type ILogger
- voidIHTTPUtilities.logHTTPRequest(ILogger logger) - -
-          Format the Source IP address, URL, URL parameters, and all form - parameters into a string suitable for the log file.
- voidIHTTPUtilities.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.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/class-use/IRandomizer.html b/javadoc/org/owasp/esapi/interfaces/class-use/IRandomizer.html deleted file mode 100644 index 30a5bd6fe..000000000 --- a/javadoc/org/owasp/esapi/interfaces/class-use/IRandomizer.html +++ /dev/null @@ -1,204 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.interfaces.IRandomizer - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.interfaces.IRandomizer

-
- - - - - - - - - -
-Packages that use IRandomizer
org.owasp.esapiReference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of IRandomizer in org.owasp.esapi
-  -

- - - - - - - - - -
Classes in org.owasp.esapi that implement IRandomizer
- classRandomizer - -
-          Reference implementation of the IRandomizer interface.
-  -

- - - - - - - - - -
Methods in org.owasp.esapi that return IRandomizer
-static IRandomizerESAPI.randomizer() - -
-           
-  -

- - - - - - - - - -
Methods in org.owasp.esapi with parameters of type IRandomizer
-static voidESAPI.setRandomizer(IRandomizer randomizer) - -
-           
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/class-use/ISecurityConfiguration.html b/javadoc/org/owasp/esapi/interfaces/class-use/ISecurityConfiguration.html deleted file mode 100644 index a051f07cd..000000000 --- a/javadoc/org/owasp/esapi/interfaces/class-use/ISecurityConfiguration.html +++ /dev/null @@ -1,204 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.interfaces.ISecurityConfiguration - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.interfaces.ISecurityConfiguration

-
- - - - - - - - - -
-Packages that use ISecurityConfiguration
org.owasp.esapiReference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of ISecurityConfiguration in org.owasp.esapi
-  -

- - - - - - - - - -
Classes in org.owasp.esapi that implement ISecurityConfiguration
- classSecurityConfiguration - -
-          The SecurityConfiguration manages all the settings used by the ESAPI in a single place.
-  -

- - - - - - - - - -
Methods in org.owasp.esapi that return ISecurityConfiguration
-static ISecurityConfigurationESAPI.securityConfiguration() - -
-           
-  -

- - - - - - - - - -
Methods in org.owasp.esapi with parameters of type ISecurityConfiguration
-static voidESAPI.setSecurityConfiguration(ISecurityConfiguration securityConfiguration) - -
-           
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/class-use/IUser.html b/javadoc/org/owasp/esapi/interfaces/class-use/IUser.html deleted file mode 100644 index 6e4a134ab..000000000 --- a/javadoc/org/owasp/esapi/interfaces/class-use/IUser.html +++ /dev/null @@ -1,349 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.interfaces.IUser - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.interfaces.IUser

-
- - - - - - - - - - - - - -
-Packages that use IUser
org.owasp.esapiReference implementations of the ESAPI interfaces. 
org.owasp.esapi.interfacesA set of interfaces modeling the most important security functions to -enterprise web applications. 
-  -

- - - - - -
-Uses of IUser in org.owasp.esapi
-  -

- - - - - - - - - -
Classes in org.owasp.esapi that implement IUser
- classUser - -
-          Reference implementation of the IUser interface.
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi that return IUser
- IUserAuthenticator.createUser(java.lang.String accountName, - java.lang.String password1, - java.lang.String password2) - -
-           
- IUserAuthenticator.getCurrentUser() - -
-           
- IUserAuthenticator.getUser(java.lang.String accountName) - -
-          Gets the user object with the matching account name or null if there is no match.
- IUserAuthenticator.getUserFromSession() - -
-          Gets the user from session.
- IUserAuthenticator.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.
-  -

- - - - - - - - - - - - - -
Methods in org.owasp.esapi with parameters of type IUser
- java.lang.StringAuthenticator.generateStrongPassword(java.lang.String oldPassword, - IUser user) - -
-           
- voidAuthenticator.setCurrentUser(IUser user) - -
-           
-  -

- - - - - -
-Uses of IUser in org.owasp.esapi.interfaces
-  -

- - - - - - - - - -
Fields in org.owasp.esapi.interfaces declared as IUser
-static IUserIUser.ANONYMOUS - -
-           
-  -

- - - - - - - - - - - - - - - - - - - - - -
Methods in org.owasp.esapi.interfaces that return IUser
- IUserIAuthenticator.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.
- IUserIAuthenticator.createUser(java.lang.String accountName, - java.lang.String password1, - java.lang.String password2) - -
-          Creates the user.
- IUserIAuthenticator.getUser(java.lang.String accountName) - -
-          Returns the User matching the provided accountName.
- IUserIAuthenticator.getCurrentUser() - -
-          Returns the currently logged in User.
-  -

- - - - - - - - - - - - - -
Methods in org.owasp.esapi.interfaces with parameters of type IUser
- java.lang.StringIAuthenticator.generateStrongPassword(java.lang.String oldPassword, - IUser user) - -
-          Generate strong password that takes into account the user's information and old password.
- voidIAuthenticator.setCurrentUser(IUser user) - -
-          Sets the currently logged in User.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/class-use/IValidator.html b/javadoc/org/owasp/esapi/interfaces/class-use/IValidator.html deleted file mode 100644 index 4bc76ff53..000000000 --- a/javadoc/org/owasp/esapi/interfaces/class-use/IValidator.html +++ /dev/null @@ -1,204 +0,0 @@ - - - - - - -Uses of Interface org.owasp.esapi.interfaces.IValidator - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Interface
org.owasp.esapi.interfaces.IValidator

-
- - - - - - - - - -
-Packages that use IValidator
org.owasp.esapiReference implementations of the ESAPI interfaces. 
-  -

- - - - - -
-Uses of IValidator in org.owasp.esapi
-  -

- - - - - - - - - -
Classes in org.owasp.esapi that implement IValidator
- classValidator - -
-          Reference implementation of the IValidator interface.
-  -

- - - - - - - - - -
Methods in org.owasp.esapi that return IValidator
-static IValidatorESAPI.validator() - -
-           
-  -

- - - - - - - - - -
Methods in org.owasp.esapi with parameters of type IValidator
-static voidESAPI.setValidator(IValidator validator) - -
-           
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/doc-files/AccessController.jpg b/javadoc/org/owasp/esapi/interfaces/doc-files/AccessController.jpg deleted file mode 100644 index 414d6a167..000000000 Binary files a/javadoc/org/owasp/esapi/interfaces/doc-files/AccessController.jpg and /dev/null differ diff --git a/javadoc/org/owasp/esapi/interfaces/doc-files/AccessReferenceMap.jpg b/javadoc/org/owasp/esapi/interfaces/doc-files/AccessReferenceMap.jpg deleted file mode 100644 index c9611c365..000000000 Binary files a/javadoc/org/owasp/esapi/interfaces/doc-files/AccessReferenceMap.jpg and /dev/null differ diff --git a/javadoc/org/owasp/esapi/interfaces/doc-files/Authenticator.jpg b/javadoc/org/owasp/esapi/interfaces/doc-files/Authenticator.jpg deleted file mode 100644 index af40202c7..000000000 Binary files a/javadoc/org/owasp/esapi/interfaces/doc-files/Authenticator.jpg and /dev/null differ diff --git a/javadoc/org/owasp/esapi/interfaces/doc-files/HTTPUtilities.jpg b/javadoc/org/owasp/esapi/interfaces/doc-files/HTTPUtilities.jpg deleted file mode 100644 index f114d52e7..000000000 Binary files a/javadoc/org/owasp/esapi/interfaces/doc-files/HTTPUtilities.jpg and /dev/null differ diff --git a/javadoc/org/owasp/esapi/interfaces/doc-files/IntrusionDetector.jpg b/javadoc/org/owasp/esapi/interfaces/doc-files/IntrusionDetector.jpg deleted file mode 100644 index 78a334585..000000000 Binary files a/javadoc/org/owasp/esapi/interfaces/doc-files/IntrusionDetector.jpg and /dev/null differ diff --git a/javadoc/org/owasp/esapi/interfaces/doc-files/Validator.jpg b/javadoc/org/owasp/esapi/interfaces/doc-files/Validator.jpg deleted file mode 100644 index 72fd9c979..000000000 Binary files a/javadoc/org/owasp/esapi/interfaces/doc-files/Validator.jpg and /dev/null differ diff --git a/javadoc/org/owasp/esapi/interfaces/package-frame.html b/javadoc/org/owasp/esapi/interfaces/package-frame.html deleted file mode 100644 index 0d303dd35..000000000 --- a/javadoc/org/owasp/esapi/interfaces/package-frame.html +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - -org.owasp.esapi.interfaces - - - - - - - - - - - -org.owasp.esapi.interfaces - - - - -
-Interfaces  - -
-IAccessController -
-IAccessReferenceMap -
-IAuthenticator -
-IEncoder -
-IEncryptedProperties -
-IEncryptor -
-IExecutor -
-IHTTPUtilities -
-IIntrusionDetector -
-ILogFactory -
-ILogger -
-IRandomizer -
-ISecurityConfiguration -
-IUser -
-IValidator
- - - - diff --git a/javadoc/org/owasp/esapi/interfaces/package-summary.html b/javadoc/org/owasp/esapi/interfaces/package-summary.html deleted file mode 100644 index af5af769a..000000000 --- a/javadoc/org/owasp/esapi/interfaces/package-summary.html +++ /dev/null @@ -1,237 +0,0 @@ - - - - - - -org.owasp.esapi.interfaces - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-

-Package org.owasp.esapi.interfaces -

-A set of interfaces modeling the most important security functions to -enterprise web applications. -

-See: -
-          Description -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Interface Summary
IAccessControllerThe IAccessController interface defines a set of methods that can be used in a wide variety of applications to - enforce access control.
IAccessReferenceMapThe 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.
IAuthenticatorThe IAuthenticator interface defines a set of methods for generating and - handling account credentials and session identifiers.
IEncoderThe IEncoder interface contains a number of methods related to encoding input - so that it will be safe for a variety of interpreters.
IEncryptedPropertiesThe IEncryptedProperties interface is a properties file where all the data is - encrypted before it is added, and decrypted when it retrieved.
IEncryptorThe IEncryptor interface provides a set of methods for performing common - encryption, random number, and hashing operations.
IExecutorThe Executor interface is used to run an OS command with less security risk.
IHTTPUtilitiesThe IHTTPUtilities interface is a collection of methods that provide additional security related to HTTP requests, - responses, sessions, cookies, headers, and logging.
IIntrusionDetectorThe IIntrusionDetector interface is intended to track security relevant events and identify attack behavior.
ILogFactory 
ILoggerThe ILogger interface defines a set of methods that can be used to log - security events.
IRandomizerThe IRandomizer interface defines a set of methods for creating - cryptographically random numbers and strings.
ISecurityConfigurationThe ISecurityConfiguration interface stores all configuration information - that directs the behavior of the ESAPI implementation.
IUserThe IUser interface represents an application user or user account.
IValidatorThe 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. -

- -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/package-tree.html b/javadoc/org/owasp/esapi/interfaces/package-tree.html deleted file mode 100644 index c3a63916d..000000000 --- a/javadoc/org/owasp/esapi/interfaces/package-tree.html +++ /dev/null @@ -1,143 +0,0 @@ - - - - - - -org.owasp.esapi.interfaces Class Hierarchy - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Hierarchy For Package org.owasp.esapi.interfaces -

-
-
-
Package Hierarchies:
All Packages
-
-

-Interface Hierarchy -

- -
- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/interfaces/package-use.html b/javadoc/org/owasp/esapi/interfaces/package-use.html deleted file mode 100644 index fd5a8b00f..000000000 --- a/javadoc/org/owasp/esapi/interfaces/package-use.html +++ /dev/null @@ -1,285 +0,0 @@ - - - - - - -Uses of Package org.owasp.esapi.interfaces - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Package
org.owasp.esapi.interfaces

-
- - - - - - - - - - - - - -
-Packages that use org.owasp.esapi.interfaces
org.owasp.esapiReference implementations of the ESAPI interfaces. 
org.owasp.esapi.interfacesA set of interfaces modeling the most important security functions to -enterprise web applications. 
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Classes in org.owasp.esapi.interfaces used by org.owasp.esapi
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.
ILogFactory - -
-           
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.
-  -

- - - - - - - - - - - -
-Classes in org.owasp.esapi.interfaces used by org.owasp.esapi.interfaces
ILogger - -
-          The ILogger interface defines a set of methods that can be used to log - security events.
IUser - -
-          The IUser interface represents an application user or user account.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/package-frame.html b/javadoc/org/owasp/esapi/package-frame.html deleted file mode 100644 index 5e9e6efd9..000000000 --- a/javadoc/org/owasp/esapi/package-frame.html +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - -org.owasp.esapi - - - - - - - - - - - -org.owasp.esapi - - - - -
-Interfaces  - -
-AccessController -
-AccessReferenceMap -
-Authenticator -
-Encoder -
-EncryptedProperties -
-Encryptor -
-Executor -
-HTTPUtilities -
-IntrusionDetector -
-LogFactory -
-Logger -
-Randomizer -
-SecurityConfiguration -
-User -
-Validator
- - - - - - -
-Classes  - -
-AllTests -
-ESAPI -
-ESAPITest -
-SafeFile -
-SecurityConfiguration.Threshold -
-StringUtilities -
-ValidationErrorList
- - - - diff --git a/javadoc/org/owasp/esapi/package-summary.html b/javadoc/org/owasp/esapi/package-summary.html deleted file mode 100644 index 0d5cdd8f3..000000000 --- a/javadoc/org/owasp/esapi/package-summary.html +++ /dev/null @@ -1,292 +0,0 @@ - - - - - - -org.owasp.esapi - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-

-Package org.owasp.esapi -

-The ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. -

-See: -
-          Description -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Interface Summary
AccessControllerThe IAccessController interface defines a set of methods that can be used in a wide variety of applications to - enforce access control.
AccessReferenceMapThe 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.
AuthenticatorThe Authenticator interface defines a set of methods for generating and - handling account credentials and session identifiers.
EncoderThe Encoder interface contains a number of methods related to encoding input - so that it will be safe for a variety of interpreters.
EncryptedPropertiesThe EncryptedProperties interface represents a properties file where all the data is - encrypted before it is added, and decrypted when it retrieved.
EncryptorThe Encryptor interface provides a set of methods for performing common - encryption, random number, and hashing operations.
ExecutorThe Executor interface is used to run an OS command with reduced security risk.
HTTPUtilitiesThe HTTPUtilities interface is a collection of methods that provide additional security related to HTTP requests, - responses, sessions, cookies, headers, and logging.
IntrusionDetectorThe IntrusionDetector interface is intended to track security relevant events and identify attack behavior.
LogFactoryThe LogFactory interface is intended to allow substitution of various logging packages, while providing - a common interface to access them.
LoggerThe Logger interface defines a set of methods that can be used to log - security events.
RandomizerThe IRandomizer interface defines a set of methods for creating - cryptographically random numbers and strings.
SecurityConfigurationThe ISecurityConfiguration interface stores all configuration information - that directs the behavior of the ESAPI implementation.
UserThe User interface represents an application user or user account.
ValidatorThe Validator interface defines a set of methods for canonicalizing and - validating untrusted input.
-  - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Class Summary
AllTestsThe Class AllTests.
ESAPIESAPI locator class to make it easy to get a concrete implementation of the - various ESAPI classes.
ESAPITestThe Class ExecutorTest.
SafeFileExtension to java.io.File to prevent against null byte injections and - other unforeseen problems resulting from unprintable characters - causing problems in path lookups.
SecurityConfiguration.ThresholdModels a simple threshold as a count and an interval, along with a set of actions to take if the threshold is exceeded.
StringUtilitiesString utilities used in various filters.
ValidationErrorListThe 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: - -

- -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/package-tree.html b/javadoc/org/owasp/esapi/package-tree.html deleted file mode 100644 index 57365eec6..000000000 --- a/javadoc/org/owasp/esapi/package-tree.html +++ /dev/null @@ -1,160 +0,0 @@ - - - - - - -org.owasp.esapi Class Hierarchy - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Hierarchy For Package org.owasp.esapi -

-
-
-
Package Hierarchies:
All Packages
-
-

-Class Hierarchy -

- -

-Interface Hierarchy -

- -
- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/package-use.html b/javadoc/org/owasp/esapi/package-use.html deleted file mode 100644 index 4809cd60f..000000000 --- a/javadoc/org/owasp/esapi/package-use.html +++ /dev/null @@ -1,389 +0,0 @@ - - - - - - -Uses of Package org.owasp.esapi - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Package
org.owasp.esapi

-
- - - - - - - - - - - - - -
-Packages that use org.owasp.esapi
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications. 
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces. 
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Classes in org.owasp.esapi used by org.owasp.esapi
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.
-  -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Classes in org.owasp.esapi used by org.owasp.esapi.reference
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.
-  -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/AccessControllerTest.html b/javadoc/org/owasp/esapi/reference/AccessControllerTest.html deleted file mode 100644 index dc5e8cc34..000000000 --- a/javadoc/org/owasp/esapi/reference/AccessControllerTest.html +++ /dev/null @@ -1,426 +0,0 @@ - - - - - - -AccessControllerTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class AccessControllerTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.reference.AccessControllerTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class AccessControllerTest
extends junit.framework.TestCase
- -

-The Class AccessControllerTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
AccessControllerTest(java.lang.String testName) - -
-          Instantiates a new access controller test.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestIsAuthorizedForBackendService() - -
-          Test of isAuthorizedForBackendService method, of class - org.owasp.esapi.AccessController.
- voidtestIsAuthorizedForData() - -
-          Test of isAuthorizedForData method, of class - org.owasp.esapi.AccessController.
- voidtestIsAuthorizedForFile() - -
-          Test of isAuthorizedForFile method, of class - org.owasp.esapi.AccessController.
- voidtestIsAuthorizedForFunction() - -
-          Test of isAuthorizedForFunction method, of class - org.owasp.esapi.AccessController.
- voidtestIsAuthorizedForURL() - -
-          Test of isAuthorizedForURL method, of class - org.owasp.esapi.AccessController.
- voidtestMatchRule() - -
-           
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-AccessControllerTest

-
-public AccessControllerTest(java.lang.String testName)
-                     throws java.lang.Exception
-
-
Instantiates a new access controller test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testMatchRule

-
-public void testMatchRule()
-
-
-
-
-
-
- -

-testIsAuthorizedForURL

-
-public void testIsAuthorizedForURL()
-                            throws java.lang.Exception
-
-
Test of isAuthorizedForURL method, of class - org.owasp.esapi.AccessController. -

-

- -
Throws: -
java.lang.Exception
-
-
-
- -

-testIsAuthorizedForFunction

-
-public void testIsAuthorizedForFunction()
-
-
Test of isAuthorizedForFunction method, of class - org.owasp.esapi.AccessController. -

-

-
-
-
-
- -

-testIsAuthorizedForData

-
-public void testIsAuthorizedForData()
-
-
Test of isAuthorizedForData method, of class - org.owasp.esapi.AccessController. -

-

-
-
-
-
- -

-testIsAuthorizedForFile

-
-public void testIsAuthorizedForFile()
-
-
Test of isAuthorizedForFile method, of class - org.owasp.esapi.AccessController. -

-

-
-
-
-
- -

-testIsAuthorizedForBackendService

-
-public void testIsAuthorizedForBackendService()
-
-
Test of isAuthorizedForBackendService method, of class - org.owasp.esapi.AccessController. -

-

-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/AccessReferenceMapTest.html b/javadoc/org/owasp/esapi/reference/AccessReferenceMapTest.html deleted file mode 100644 index 4cc6e7999..000000000 --- a/javadoc/org/owasp/esapi/reference/AccessReferenceMapTest.html +++ /dev/null @@ -1,428 +0,0 @@ - - - - - - -AccessReferenceMapTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class AccessReferenceMapTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.reference.AccessReferenceMapTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class AccessReferenceMapTest
extends junit.framework.TestCase
- -

-The Class AccessReferenceMapTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
AccessReferenceMapTest(java.lang.String testName) - -
-          Instantiates a new access reference map test.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestAddDirectReference() - -
-           
- voidtestGetDirectReference() - -
-          Test of getDirectReference method, of class - org.owasp.esapi.AccessReferenceMap.
- voidtestGetIndirectReference() - -
-          Test of getIndirectReference method, of class - org.owasp.esapi.AccessReferenceMap.
- voidtestIterator() - -
-          Test of iterator method, of class org.owasp.esapi.AccessReferenceMap.
- voidtestRemoveDirectReference() - -
-           
- voidtestUpdate() - -
-          Test of update method, of class org.owasp.esapi.AccessReferenceMap.
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-AccessReferenceMapTest

-
-public AccessReferenceMapTest(java.lang.String testName)
-
-
Instantiates a new access reference map test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testUpdate

-
-public void testUpdate()
-                throws AuthenticationException,
-                       EncryptionException
-
-
Test of update method, of class org.owasp.esapi.AccessReferenceMap. -

-

- -
Throws: -
AuthenticationException - the authentication exception -
EncryptionException
-
-
-
- -

-testIterator

-
-public void testIterator()
-
-
Test of iterator method, of class org.owasp.esapi.AccessReferenceMap. -

-

-
-
-
-
- -

-testGetIndirectReference

-
-public void testGetIndirectReference()
-
-
Test of getIndirectReference method, of class - org.owasp.esapi.AccessReferenceMap. -

-

-
-
-
-
- -

-testGetDirectReference

-
-public void testGetDirectReference()
-                            throws AccessControlException
-
-
Test of getDirectReference method, of class - org.owasp.esapi.AccessReferenceMap. -

-

- -
Throws: -
AccessControlException - the access control exception
-
-
-
- -

-testAddDirectReference

-
-public void testAddDirectReference()
-                            throws AccessControlException
-
-
- -
Throws: -
AccessControlException
-
-
-
- -

-testRemoveDirectReference

-
-public void testRemoveDirectReference()
-                               throws AccessControlException
-
-
- -
Throws: -
AccessControlException
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/AuthenticatorTest.html b/javadoc/org/owasp/esapi/reference/AuthenticatorTest.html deleted file mode 100644 index 2423f5d88..000000000 --- a/javadoc/org/owasp/esapi/reference/AuthenticatorTest.html +++ /dev/null @@ -1,678 +0,0 @@ - - - - - - -AuthenticatorTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class AuthenticatorTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.reference.AuthenticatorTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class AuthenticatorTest
extends junit.framework.TestCase
- -

-The Class AuthenticatorTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
AuthenticatorTest(java.lang.String testName) - -
-          Instantiates a new authenticator test.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestCreateUser() - -
-          Test of createAccount method, of class org.owasp.esapi.Authenticator.
- voidtestExists() - -
-          Test of exists method, of class org.owasp.esapi.Authenticator.
- voidtestGenerateStrongPassword() - -
-          Test of generateStrongPassword method, of class - org.owasp.esapi.Authenticator.
- voidtestGetCurrentUser() - -
-          Test of getCurrentUser method, of class org.owasp.esapi.Authenticator.
- voidtestGetUser() - -
-          Test of getUser method, of class org.owasp.esapi.Authenticator.
- voidtestGetUserFromRememberToken() - -
-           
- voidtestGetUserFromSession() - -
-          Test get user from session.
- voidtestGetUserNames() - -
-          Test get user names.
- voidtestHashPassword() - -
-          Test of hashPassword method, of class org.owasp.esapi.Authenticator.
- voidtestLogin() - -
-          Test of login method, of class org.owasp.esapi.Authenticator.
- voidtestMain() - -
-          Test of main method, of class org.owasp.esapi.Authenticator.
- voidtestRemoveUser() - -
-          Test of removeAccount method, of class org.owasp.esapi.Authenticator.
- voidtestSaveUsers() - -
-          Test of saveUsers method, of class org.owasp.esapi.Authenticator.
- voidtestSetCurrentUser() - -
-          Test of setCurrentUser method, of class org.owasp.esapi.Authenticator.
- voidtestSetCurrentUserWithRequest() - -
-          Test of setCurrentUser method, of class org.owasp.esapi.Authenticator.
- voidtestValidatePasswordStrength() - -
-          Test of validatePasswordStrength method, of class - org.owasp.esapi.Authenticator.
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-AuthenticatorTest

-
-public AuthenticatorTest(java.lang.String testName)
-
-
Instantiates a new authenticator test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testCreateUser

-
-public void testCreateUser()
-                    throws AuthenticationException,
-                           EncryptionException
-
-
Test of createAccount method, of class org.owasp.esapi.Authenticator. -

-

- -
Throws: -
AuthenticationException - the authentication exception -
EncryptionException
-
-
-
- -

-testGenerateStrongPassword

-
-public void testGenerateStrongPassword()
-                                throws AuthenticationException
-
-
Test of generateStrongPassword method, of class - org.owasp.esapi.Authenticator. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testGetCurrentUser

-
-public void testGetCurrentUser()
-                        throws java.lang.Exception
-
-
Test of getCurrentUser method, of class org.owasp.esapi.Authenticator. -

-

- -
Throws: -
java.lang.InterruptedException - * -
AuthenticationException - the authentication exception -
java.lang.Exception
-
-
-
- -

-testGetUser

-
-public void testGetUser()
-                 throws AuthenticationException
-
-
Test of getUser method, of class org.owasp.esapi.Authenticator. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testGetUserFromRememberToken

-
-public void testGetUserFromRememberToken()
-                                  throws AuthenticationException
-
-
- -
Throws: -
AuthenticationException
-
-
-
- -

-testGetUserFromSession

-
-public void testGetUserFromSession()
-                            throws AuthenticationException
-
-
Test get user from session. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testGetUserNames

-
-public void testGetUserNames()
-                      throws AuthenticationException
-
-
Test get user names. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testHashPassword

-
-public void testHashPassword()
-                      throws EncryptionException
-
-
Test of hashPassword method, of class org.owasp.esapi.Authenticator. -

-

- -
Throws: -
EncryptionException
-
-
-
- -

-testLogin

-
-public void testLogin()
-               throws AuthenticationException
-
-
Test of login method, of class org.owasp.esapi.Authenticator. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testRemoveUser

-
-public void testRemoveUser()
-                    throws java.lang.Exception
-
-
Test of removeAccount method, of class org.owasp.esapi.Authenticator. -

-

- -
Throws: -
java.lang.Exception - the exception
-
-
-
- -

-testSaveUsers

-
-public void testSaveUsers()
-                   throws java.lang.Exception
-
-
Test of saveUsers method, of class org.owasp.esapi.Authenticator. -

-

- -
Throws: -
java.lang.Exception - the exception
-
-
-
- -

-testSetCurrentUser

-
-public void testSetCurrentUser()
-                        throws AuthenticationException
-
-
Test of setCurrentUser method, of class org.owasp.esapi.Authenticator. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testSetCurrentUserWithRequest

-
-public void testSetCurrentUserWithRequest()
-                                   throws AuthenticationException
-
-
Test of setCurrentUser method, of class org.owasp.esapi.Authenticator. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testValidatePasswordStrength

-
-public void testValidatePasswordStrength()
-                                  throws AuthenticationException
-
-
Test of validatePasswordStrength method, of class - org.owasp.esapi.Authenticator. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testExists

-
-public void testExists()
-                throws java.lang.Exception
-
-
Test of exists method, of class org.owasp.esapi.Authenticator. -

-

- -
Throws: -
java.lang.Exception - the exception
-
-
-
- -

-testMain

-
-public void testMain()
-              throws java.lang.Exception
-
-
Test of main method, of class org.owasp.esapi.Authenticator. -

-

- -
Throws: -
java.lang.Exception
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/DefaultEncoder.html b/javadoc/org/owasp/esapi/reference/DefaultEncoder.html deleted file mode 100644 index 67be4e272..000000000 --- a/javadoc/org/owasp/esapi/reference/DefaultEncoder.html +++ /dev/null @@ -1,844 +0,0 @@ - - - - - - -DefaultEncoder - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class DefaultEncoder

-
-java.lang.Object
-  extended byorg.owasp.esapi.reference.DefaultEncoder
-
-
-
All Implemented Interfaces:
Encoder
-
-
-
-
public class DefaultEncoder
extends java.lang.Object
implements Encoder
- -

-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
-
See Also:
Encoder
-
- -

- - - - - - - - - - -
-Field Summary
- - - - - - - -
Fields inherited from interface org.owasp.esapi.Encoder
CHAR_ALPHANUMERICS, CHAR_DIGITS, CHAR_LETTERS, CHAR_LOWERS, CHAR_PASSWORD_DIGITS, CHAR_PASSWORD_LETTERS, CHAR_PASSWORD_LOWERS, CHAR_PASSWORD_SPECIALS, CHAR_PASSWORD_UPPERS, CHAR_SPECIALS, CHAR_UPPERS
-  - - - - - - - - - - -
-Constructor Summary
DefaultEncoder() - -
-           
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- java.lang.Stringcanonicalize(java.lang.String input) - -
-          Simplifies encoded characters to their - simplest form so that they can be properly validated.
- java.lang.Stringcanonicalize(java.lang.String input, - boolean strict) - -
-          Strict mode throws an exception when any double encoded data is detected.
- byte[]decodeFromBase64(java.lang.String input) - -
-          Decode data encoded with BASE-64 encoding.
- java.lang.StringdecodeFromURL(java.lang.String input) - -
-          Decode from URL.
- java.lang.StringencodeForBase64(byte[] input, - boolean wrap) - -
-          Encode for Base64.
- java.lang.StringencodeForCSS(java.lang.String input) - -
-          http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
- java.lang.StringencodeForDN(java.lang.String input) - -
-          Encode data for use in an LDAP distinguished name.
- java.lang.StringencodeForHTML(java.lang.String input) - -
-          Encode the input string using HTML entity encoding.
- java.lang.StringencodeForHTMLAttribute(java.lang.String input) - -
-          Encode data for use in HTML attributes.
- java.lang.StringencodeForJavaScript(java.lang.String input) - -
-          Encode data for insertion inside a data value in JavaScript.
- java.lang.StringencodeForLDAP(java.lang.String input) - -
-          Encode data for use in LDAP queries.
- java.lang.StringencodeForSQL(Codec codec, - java.lang.String input) - -
-          This method is not recommended.
- java.lang.StringencodeForURL(java.lang.String input) - -
-          Encode for use in a URL.
- java.lang.StringencodeForVBScript(java.lang.String input) - -
-          Encode data for insertion inside a data value in a visual basic script.
- java.lang.StringencodeForXML(java.lang.String input) - -
-          Encode data for use in an XML element.
- java.lang.StringencodeForXMLAttribute(java.lang.String input) - -
-          Encode data for use in an XML attribute.
- java.lang.StringencodeForXPath(java.lang.String input) - -
-          This implementation encodes almost everything and may overencode.
- java.lang.Stringnormalize(java.lang.String input) - -
-          Normalizes special characters down to ASCII using the Normalizer built - into Java.
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-DefaultEncoder

-
-public DefaultEncoder()
-
-
- - - - - - - - -
-Method Detail
- -

-canonicalize

-
-public java.lang.String canonicalize(java.lang.String input)
-
-
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 - -
- &lt;
- 
- - or - -
- %26lt;
- 
- - or - -
- &lt;
- 
. - - 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. -

-

-
Specified by:
canonicalize in interface Encoder
-
-
-
Parameters:
input - the text to canonicalize -
Returns:
a String containing the canonicalized text -
Throws: -
IntrusionException
See Also:
org.owasp.esapi.Validator#canonicalize(java.lang.String)
-
-
-
- -

-canonicalize

-
-public java.lang.String canonicalize(java.lang.String input,
-                                     boolean strict)
-
-
Strict mode throws an exception when any double encoded data is detected. -

-

-
Specified by:
canonicalize in interface Encoder
-
-
-
Parameters:
input - the text to canonicalize
strict - true if checking for double encoding is desired, false otherwise -
Returns:
a String containing the canonicalized text
-
-
-
- -

-normalize

-
-public java.lang.String normalize(java.lang.String input)
-
-
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. -

-

-
Specified by:
normalize in interface Encoder
-
-
-
Parameters:
input - the text to normalize -
Returns:
a normalized String
See Also:
org.owasp.esapi.Validator#normalize(java.lang.String)
-
-
-
- -

-encodeForHTML

-
-public java.lang.String encodeForHTML(java.lang.String input)
-
-
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 -

-

-
Specified by:
encodeForHTML in interface Encoder
-
-
-
Parameters:
input - the text to encode for HTML -
Returns:
input encoded for HTML
See Also:
Encoder.encodeForHTML(java.lang.String)
-
-
-
- -

-encodeForHTMLAttribute

-
-public java.lang.String encodeForHTMLAttribute(java.lang.String input)
-
-
Description copied from interface: Encoder
-
Encode data for use in HTML attributes. -

-

-
Specified by:
encodeForHTMLAttribute in interface Encoder
-
-
-
Parameters:
input - the text to encode for an HTML attribute -
Returns:
input encoded for use as an HTML attribute
-
-
-
- -

-encodeForCSS

-
-public java.lang.String encodeForCSS(java.lang.String input)
-
-
http://www.w3.org/TR/CSS21/syndata.html#escaped-characters -

-

-
Specified by:
encodeForCSS in interface Encoder
-
-
-
Parameters:
input - the text to encode for CSS -
Returns:
input encoded for CSS
-
-
-
- -

-encodeForJavaScript

-
-public java.lang.String encodeForJavaScript(java.lang.String input)
-
-
Description copied from interface: Encoder
-
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. -

-

-
Specified by:
encodeForJavaScript in interface Encoder
-
-
-
Parameters:
input - the text to encode for JavaScript -
Returns:
input encoded for use in JavaScript
-
-
-
- -

-encodeForVBScript

-
-public java.lang.String encodeForVBScript(java.lang.String input)
-
-
Description copied from interface: Encoder
-
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. -

-

-
Specified by:
encodeForVBScript in interface Encoder
-
-
-
Parameters:
input - the text to encode for VBScript -
Returns:
input encoded for use in VBScript
-
-
-
- -

-encodeForSQL

-
-public java.lang.String encodeForSQL(Codec codec,
-                                     java.lang.String input)
-
-
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. -

-

-
Specified by:
encodeForSQL in interface Encoder
-
-
-
Parameters:
input - the input
codec - a Codec that declares which database 'input' is being encoded for (ie. MySQL, Oracle, etc.) -
Returns:
the string
See Also:
org.owasp.esapi.Encoder#encodeForSQL(java.lang.String)
-
-
-
- -

-encodeForLDAP

-
-public java.lang.String encodeForLDAP(java.lang.String input)
-
-
Description copied from interface: Encoder
-
Encode data for use in LDAP queries. -

-

-
Specified by:
encodeForLDAP in interface Encoder
-
-
-
Parameters:
input - the text to encode for LDAP -
Returns:
input encoded for use in LDAP
-
-
-
- -

-encodeForDN

-
-public java.lang.String encodeForDN(java.lang.String input)
-
-
Description copied from interface: Encoder
-
Encode data for use in an LDAP distinguished name. -

-

-
Specified by:
encodeForDN in interface Encoder
-
-
-
Parameters:
input - the text to encode for an LDAP distinguished name -
Returns:
input encoded for use in an LDAP distinguished name
-
-
-
- -

-encodeForXPath

-
-public java.lang.String encodeForXPath(java.lang.String input)
-
-
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. -

-

-
Specified by:
encodeForXPath in interface Encoder
-
-
-
Parameters:
input - the input -
Returns:
the string
See Also:
Encoder.encodeForXPath(java.lang.String)
-
-
-
- -

-encodeForXML

-
-public java.lang.String encodeForXML(java.lang.String input)
-
-
Description copied from interface: Encoder
-
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. -

-

-
Specified by:
encodeForXML in interface Encoder
-
-
-
Parameters:
input - the text to encode for XML -
Returns:
input encoded for use in XML
-
-
-
- -

-encodeForXMLAttribute

-
-public java.lang.String encodeForXMLAttribute(java.lang.String input)
-
-
Description copied from interface: Encoder
-
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. -

-

-
Specified by:
encodeForXMLAttribute in interface Encoder
-
-
-
Parameters:
input - the text to encode for use as an XML attribute -
Returns:
input encoded for use in an XML attribute
-
-
-
- -

-encodeForURL

-
-public java.lang.String encodeForURL(java.lang.String input)
-                              throws EncodingException
-
-
Description copied from interface: Encoder
-
Encode for use in a URL. This method performs URL encoding" - on the entire string. -

-

-
Specified by:
encodeForURL in interface Encoder
-
-
-
Parameters:
input - the text to encode for use in a URL -
Returns:
input encoded for use in a URL -
Throws: -
EncodingException - if encoding fails
-
-
-
- -

-decodeFromURL

-
-public java.lang.String decodeFromURL(java.lang.String input)
-                               throws EncodingException
-
-
Description copied from interface: Encoder
-
Decode from URL. Implementations should first canonicalize and - detect any double-encoding. If this check passes, then the data is decoded using URL - decoding. -

-

-
Specified by:
decodeFromURL in interface Encoder
-
-
-
Parameters:
input - the text to decode from an encoded URL -
Returns:
the decoded URL value -
Throws: -
EncodingException - if decoding fails
-
-
-
- -

-encodeForBase64

-
-public java.lang.String encodeForBase64(byte[] input,
-                                        boolean wrap)
-
-
Description copied from interface: Encoder
-
Encode for Base64. -

-

-
Specified by:
encodeForBase64 in interface Encoder
-
-
-
Parameters:
input - the text to encode for Base64
wrap - -
Returns:
input encoded for Base64
-
-
-
- -

-decodeFromBase64

-
-public byte[] decodeFromBase64(java.lang.String input)
-                        throws java.io.IOException
-
-
Description copied from interface: Encoder
-
Decode data encoded with BASE-64 encoding. -

-

-
Specified by:
decodeFromBase64 in interface Encoder
-
-
-
Parameters:
input - the Base64 text to decode -
Returns:
input decoded from Base64 -
Throws: -
java.io.IOException
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/DefaultEncryptedProperties.html b/javadoc/org/owasp/esapi/reference/DefaultEncryptedProperties.html deleted file mode 100644 index 66b4b26a0..000000000 --- a/javadoc/org/owasp/esapi/reference/DefaultEncryptedProperties.html +++ /dev/null @@ -1,423 +0,0 @@ - - - - - - -DefaultEncryptedProperties - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class DefaultEncryptedProperties

-
-java.lang.Object
-  extended byorg.owasp.esapi.reference.DefaultEncryptedProperties
-
-
-
All Implemented Interfaces:
EncryptedProperties
-
-
-
-
public class DefaultEncryptedProperties
extends java.lang.Object
implements EncryptedProperties
- -

-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
-
See Also:
EncryptedProperties
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
DefaultEncryptedProperties() - -
-          Instantiates a new encrypted properties.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- java.lang.StringgetProperty(java.lang.String key) - -
-          Gets the property value from the encrypted store, decrypts it, and returns the plaintext value to the caller.
- java.util.SetkeySet() - -
-          Key set.
- voidload(java.io.InputStream in) - -
-          Load.
-static voidmain(java.lang.String[] args) - -
-          The main method.
- java.lang.StringsetProperty(java.lang.String key, - java.lang.String value) - -
-          Encrypts the plaintext property value and stores the ciphertext value in the encrypted store.
- voidstore(java.io.OutputStream out, - java.lang.String comments) - -
-          Store.
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-DefaultEncryptedProperties

-
-public DefaultEncryptedProperties()
-
-
Instantiates a new encrypted properties. -

-

- - - - - - - - -
-Method Detail
- -

-getProperty

-
-public java.lang.String getProperty(java.lang.String key)
-                             throws EncryptionException
-
-
Description copied from interface: EncryptedProperties
-
Gets the property value from the encrypted store, decrypts it, and returns the plaintext value to the caller. -

-

-
Specified by:
getProperty in interface EncryptedProperties
-
-
-
Parameters:
key - the key -
Returns:
the decrypted property value -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-setProperty

-
-public java.lang.String setProperty(java.lang.String key,
-                                    java.lang.String value)
-                             throws EncryptionException
-
-
Description copied from interface: EncryptedProperties
-
Encrypts the plaintext property value and stores the ciphertext value in the encrypted store. -

-

-
Specified by:
setProperty in interface EncryptedProperties
-
-
-
Parameters:
key - the key
value - the value -
Returns:
the encrypted property value -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-keySet

-
-public java.util.Set keySet()
-
-
Key set. -

-

-
Specified by:
keySet in interface EncryptedProperties
-
-
- -
Returns:
the set
-
-
-
- -

-load

-
-public void load(java.io.InputStream in)
-          throws java.io.IOException
-
-
Load. -

-

-
Specified by:
load in interface EncryptedProperties
-
-
-
Parameters:
in - the in -
Throws: -
java.io.IOException - Signals that an I/O exception has occurred.
-
-
-
- -

-store

-
-public void store(java.io.OutputStream out,
-                  java.lang.String comments)
-           throws java.io.IOException
-
-
Store. -

-

-
Specified by:
store in interface EncryptedProperties
-
-
-
Parameters:
out - the out
comments - the comments -
Throws: -
java.io.IOException - Signals that an I/O exception has occurred.
-
-
-
- -

-main

-
-public static void main(java.lang.String[] args)
-                 throws java.lang.Exception
-
-
The main method. -

-

-
-
-
-
Parameters:
args - the arguments -
Throws: -
java.lang.Exception - the exception
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/DefaultExecutor.html b/javadoc/org/owasp/esapi/reference/DefaultExecutor.html deleted file mode 100644 index 9878a8cf4..000000000 --- a/javadoc/org/owasp/esapi/reference/DefaultExecutor.html +++ /dev/null @@ -1,289 +0,0 @@ - - - - - - -DefaultExecutor - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class DefaultExecutor

-
-java.lang.Object
-  extended byorg.owasp.esapi.reference.DefaultExecutor
-
-
-
All Implemented Interfaces:
Executor
-
-
-
-
public class DefaultExecutor
extends java.lang.Object
implements Executor
- -

-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
-
See Also:
Executor
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
DefaultExecutor() - -
-           
-  - - - - - - - - - - - -
-Method Summary
- java.lang.StringexecuteSystemCommand(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.
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-DefaultExecutor

-
-public DefaultExecutor()
-
-
- - - - - - - - -
-Method Detail
- -

-executeSystemCommand

-
-public java.lang.String executeSystemCommand(java.io.File executable,
-                                             java.util.List params,
-                                             java.io.File workdir,
-                                             int timeoutSeconds)
-                                      throws ExecutorException
-
-
Description copied from interface: Executor
-
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. -

-

-
Specified by:
executeSystemCommand in interface Executor
-
-
-
Parameters:
params - the parameters of the command being executed
workdir - the working directory
timeoutSeconds - the amount of time to allow this process to run -
Returns:
the output of the command being run -
Throws: -
ExecutorException - the service exception
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/DefaultHTTPUtilities.html b/javadoc/org/owasp/esapi/reference/DefaultHTTPUtilities.html deleted file mode 100644 index 7ee801069..000000000 --- a/javadoc/org/owasp/esapi/reference/DefaultHTTPUtilities.html +++ /dev/null @@ -1,1026 +0,0 @@ - - - - - - -DefaultHTTPUtilities - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class DefaultHTTPUtilities

-
-java.lang.Object
-  extended byorg.owasp.esapi.reference.DefaultHTTPUtilities
-
-
-
All Implemented Interfaces:
HTTPUtilities
-
-
-
-
public class DefaultHTTPUtilities
extends java.lang.Object
implements HTTPUtilities
- -

-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
-
See Also:
HTTPUtilities
-
- -

- - - - - - - - - - -
-Field Summary
- - - - - - - -
Fields inherited from interface org.owasp.esapi.HTTPUtilities
REMEMBER_TOKEN_COOKIE_NAME
-  - - - - - - - - - - -
-Constructor Summary
DefaultHTTPUtilities() - -
-           
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- java.lang.StringaddCSRFToken(java.lang.String href) - -
-          Adds the current user's CSRF token (see User.getCSRFToken()) to the URL for purposes of preventing CSRF attacks.
- voidassertSecureRequest(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.HttpSessionchangeSessionIdentifier(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.StringdecryptHiddenField(java.lang.String encrypted) - -
-          Decrypts an encrypted hidden field value and returns the cleartext.
- java.util.MapdecryptQueryString(java.lang.String encrypted) - -
-          Takes an encrypted querystring and returns a Map containing the original parameters.
- java.util.MapdecryptStateFromCookie(javax.servlet.http.HttpServletRequest request) - -
-          Retrieves a map of data from a cookie encrypted with encryptStateInCookie().
- java.lang.StringencryptHiddenField(java.lang.String value) - -
-          Encrypts a hidden field value for use in HTML.
- java.lang.StringencryptQueryString(java.lang.String query) - -
-          Takes a querystring (i.e.
- voidencryptStateInCookie(javax.servlet.http.HttpServletResponse response, - java.util.Map cleartext) - -
-          Stores a Map of data in an encrypted cookie.
- javax.servlet.http.CookiegetCookie(javax.servlet.http.HttpServletRequest request, - java.lang.String name) - -
-          Returns the first cookie matching the provided name.
- java.lang.StringgetCSRFToken() - -
-          Returns the current user's CSRF token.
- SafeRequestgetCurrentRequest() - -
-          Retrieves the current HttpServletRequest
- SafeResponsegetCurrentResponse() - -
-          Retrieves the current HttpServletResponse
- java.util.ListgetSafeFileUploads(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.
- booleanisSecureChannel(javax.servlet.http.HttpServletRequest request) - -
-          Returns true if the request was transmitted over an SSL enabled - connection.
- voidkillAllCookies(javax.servlet.http.HttpServletRequest request, - javax.servlet.http.HttpServletResponse response) - -
-          Kill all cookies received in the last request from the browser.
- voidkillCookie(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.
- voidlogHTTPRequest(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.
- voidlogHTTPRequest(javax.servlet.http.HttpServletRequest request, - Logger logger, - java.util.List parameterNamesToObfuscate) - -
-          Formats an HTTP request into a log suitable string.
- voidsafeSendForward(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.
- voidsafeSetContentType(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.
- voidsetCurrentHTTP(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)
- voidsetNoCacheHeaders(javax.servlet.http.HttpServletResponse response) - -
-          Set headers to protect sensitive information against being cached in the - browser.
- java.lang.StringsetRememberToken(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.
- voidverifyCSRFToken(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.
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-DefaultHTTPUtilities

-
-public DefaultHTTPUtilities()
-
-
- - - - - - - - -
-Method Detail
- -

-addCSRFToken

-
-public java.lang.String addCSRFToken(java.lang.String href)
-
-
Description copied from interface: HTTPUtilities
-
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. -

-

-
Specified by:
addCSRFToken in interface HTTPUtilities
-
-
-
Parameters:
href - the URL to which the CSRF token will be appended -
Returns:
the updated URL with the CSRF token parameter added
See Also:
HTTPUtilities.addCSRFToken(java.lang.String)
-
-
-
- -

-getCookie

-
-public javax.servlet.http.Cookie getCookie(javax.servlet.http.HttpServletRequest request,
-                                           java.lang.String name)
-
-
Returns the first cookie matching the provided name. -

-

-
Specified by:
getCookie in interface HTTPUtilities
-
-
-
Parameters:
name - -
Returns:
-
-
-
- -

-getCSRFToken

-
-public java.lang.String getCSRFToken()
-
-
Description copied from interface: HTTPUtilities
-
Returns the current user's CSRF token. If there is no current user then return null. -

-

-
Specified by:
getCSRFToken in interface HTTPUtilities
-
-
- -
Returns:
the current users CSRF token
See Also:
HTTPUtilities.getCSRFToken()
-
-
-
- -

-setRememberToken

-
-public 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. 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. -

-

-
Specified by:
setRememberToken in interface HTTPUtilities
-
-
-
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 -
Returns:
encrypted "Remember Me" token stored as a String
-
-
-
- -

-assertSecureRequest

-
-public void assertSecureRequest(javax.servlet.http.HttpServletRequest request)
-                         throws AccessControlException
-
-
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. -

-

-
Specified by:
assertSecureRequest in interface HTTPUtilities
-
-
- -
Throws: -
AccessControlException - if security constraints are not met
-
-
-
- -

-changeSessionIdentifier

-
-public javax.servlet.http.HttpSession changeSessionIdentifier(javax.servlet.http.HttpServletRequest request)
-                                                       throws AuthenticationException
-
-
Description copied from interface: HTTPUtilities
-
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 -

-

-
Specified by:
changeSessionIdentifier in interface HTTPUtilities
-
-
- -
Returns:
the new HttpSession with a changed id -
Throws: -
AuthenticationException
-
-
-
- -

-verifyCSRFToken

-
-public void verifyCSRFToken(javax.servlet.http.HttpServletRequest request)
-                     throws IntrusionException
-
-
Description copied from interface: HTTPUtilities
-
Checks the CSRF token in the URL (see User.getCSRFToken()) against the user's CSRF token and - throws an IntrusionException if it is missing. -

-

-
Specified by:
verifyCSRFToken in interface HTTPUtilities
-
-
- -
Throws: -
IntrusionException - if CSRF token is missing or incorrect
-
-
-
- -

-decryptHiddenField

-
-public java.lang.String decryptHiddenField(java.lang.String encrypted)
-
-
Description copied from interface: HTTPUtilities
-
Decrypts an encrypted hidden field value and returns the cleartext. If the field does not decrypt properly, - an IntrusionException is thrown to indicate tampering. -

-

-
Specified by:
decryptHiddenField in interface HTTPUtilities
-
-
-
Parameters:
encrypted - hidden field value to decrypt -
Returns:
decrypted hidden field value stored as a String
-
-
-
- -

-decryptQueryString

-
-public java.util.Map decryptQueryString(java.lang.String encrypted)
-                                 throws EncryptionException
-
-
Description copied from interface: HTTPUtilities
-
Takes an encrypted querystring and returns a Map containing the original parameters. -

-

-
Specified by:
decryptQueryString in interface HTTPUtilities
-
-
-
Parameters:
encrypted - the encrypted querystring to decrypt -
Returns:
a Map object containing the decrypted querystring -
Throws: -
EncryptionException
-
-
-
- -

-decryptStateFromCookie

-
-public java.util.Map decryptStateFromCookie(javax.servlet.http.HttpServletRequest request)
-                                     throws EncryptionException
-
-
Description copied from interface: HTTPUtilities
-
Retrieves a map of data from a cookie encrypted with encryptStateInCookie(). -

-

-
Specified by:
decryptStateFromCookie in interface HTTPUtilities
-
-
- -
Returns:
a map containing the decrypted cookie state value -
Throws: -
EncryptionException
See Also:
org.owasp.esapi.HTTPUtilities#decryptStateFromCookie()
-
-
-
- -

-encryptHiddenField

-
-public java.lang.String encryptHiddenField(java.lang.String value)
-                                    throws EncryptionException
-
-
Description copied from interface: HTTPUtilities
-
Encrypts a hidden field value for use in HTML. -

-

-
Specified by:
encryptHiddenField in interface HTTPUtilities
-
-
-
Parameters:
value - the cleartext value of the hidden field -
Returns:
the encrypted value of the hidden field -
Throws: -
EncryptionException
-
-
-
- -

-encryptQueryString

-
-public java.lang.String encryptQueryString(java.lang.String query)
-                                    throws EncryptionException
-
-
Description copied from interface: HTTPUtilities
-
Takes a querystring (i.e. everything after the ? in the URL) and returns an encrypted string containing the parameters. -

-

-
Specified by:
encryptQueryString in interface HTTPUtilities
-
-
-
Parameters:
query - the querystring to encrypt -
Returns:
encrypted querystring stored as a String -
Throws: -
EncryptionException
-
-
-
- -

-encryptStateInCookie

-
-public void encryptStateInCookie(javax.servlet.http.HttpServletResponse response,
-                                 java.util.Map cleartext)
-                          throws EncryptionException
-
-
Description copied from interface: HTTPUtilities
-
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. -

-

-
Specified by:
encryptStateInCookie in interface HTTPUtilities
-
-
- -
Throws: -
EncryptionException
See Also:
org.owasp.esapi.HTTPUtilities#encryptStateInCookie(java.util.Map)
-
-
-
- -

-getSafeFileUploads

-
-public java.util.List getSafeFileUploads(javax.servlet.http.HttpServletRequest request,
-                                         java.io.File tempDir,
-                                         java.io.File finalDir)
-                                  throws ValidationException
-
-
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. -

-

-
Specified by:
getSafeFileUploads in interface HTTPUtilities
-
-
-
Parameters:
tempDir - the temporary directory
finalDir - the final directory -
Returns:
list of File objects for new files in final directory -
Throws: -
ValidationException - if the file fails validation
See Also:
org.owasp.esapi.HTTPUtilities#safeGetFileUploads(java.io.File, java.io.File)
-
-
-
- -

-isSecureChannel

-
-public boolean isSecureChannel(javax.servlet.http.HttpServletRequest request)
-
-
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. -

-

-
-
-
-
-
-
-
- -

-killAllCookies

-
-public void killAllCookies(javax.servlet.http.HttpServletRequest request,
-                           javax.servlet.http.HttpServletResponse response)
-
-
Description copied from interface: HTTPUtilities
-
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. -

-

-
Specified by:
killAllCookies in interface HTTPUtilities
-
-
-
-
-
-
- -

-killCookie

-
-public void killCookie(javax.servlet.http.HttpServletRequest request,
-                       javax.servlet.http.HttpServletResponse response,
-                       java.lang.String name)
-
-
Description copied from interface: HTTPUtilities
-
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. -

-

-
Specified by:
killCookie in interface HTTPUtilities
-
-
-
-
-
-
- -

-safeSendForward

-
-public void safeSendForward(javax.servlet.http.HttpServletRequest request,
-                            javax.servlet.http.HttpServletResponse response,
-                            java.lang.String context,
-                            java.lang.String location)
-                     throws AccessControlException,
-                            javax.servlet.ServletException,
-                            java.io.IOException
-
-
Description copied from interface: HTTPUtilities
-
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. -

-

-
Specified by:
safeSendForward in interface HTTPUtilities
-
-
-
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.
location - the URL to forward to -
Throws: -
javax.servlet.ServletException -
AccessControlException -
java.io.IOException
-
-
-
- -

-safeSetContentType

-
-public 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. 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. -

-

-
Specified by:
safeSetContentType in interface HTTPUtilities
-
-
-
See Also:
org.owasp.esapi.HTTPUtilities#safeSetContentType(java.lang.String)
-
-
-
- -

-setNoCacheHeaders

-
-public void setNoCacheHeaders(javax.servlet.http.HttpServletResponse response)
-
-
Set headers to protect sensitive information against being cached in the - browser. -

-

-
Specified by:
setNoCacheHeaders in interface HTTPUtilities
-
-
-
See Also:
HTTPUtilities.setNoCacheHeaders(javax.servlet.http.HttpServletResponse)
-
-
-
- -

-getCurrentRequest

-
-public SafeRequest getCurrentRequest()
-
-
Description copied from interface: HTTPUtilities
-
Retrieves the current HttpServletRequest -

-

-
Specified by:
getCurrentRequest in interface HTTPUtilities
-
-
- -
Returns:
the current request
-
-
-
- -

-getCurrentResponse

-
-public SafeResponse getCurrentResponse()
-
-
Description copied from interface: HTTPUtilities
-
Retrieves the current HttpServletResponse -

-

-
Specified by:
getCurrentResponse in interface HTTPUtilities
-
-
- -
Returns:
the current response
-
-
-
- -

-setCurrentHTTP

-
-public void setCurrentHTTP(javax.servlet.http.HttpServletRequest request,
-                           javax.servlet.http.HttpServletResponse response)
-
-
Description copied from interface: HTTPUtilities
-
Stores the current HttpRequest and HttpResponse so that they may be readily accessed throughout - ESAPI (and elsewhere) -

-

-
Specified by:
setCurrentHTTP in interface HTTPUtilities
-
-
-
Parameters:
request - the current request
response - the current response
-
-
-
- -

-logHTTPRequest

-
-public void logHTTPRequest(javax.servlet.http.HttpServletRequest request,
-                           Logger logger)
-
-
Description copied from interface: HTTPUtilities
-
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. -

-

-
Specified by:
logHTTPRequest in interface HTTPUtilities
-
-
-
Parameters:
logger - the logger to write the request to
-
-
-
- -

-logHTTPRequest

-
-public void logHTTPRequest(javax.servlet.http.HttpServletRequest request,
-                           Logger logger,
-                           java.util.List parameterNamesToObfuscate)
-
-
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. -

-

-
Specified by:
logHTTPRequest in interface HTTPUtilities
-
-
-
Parameters:
logger - the logger to write the request to
parameterNamesToObfuscate - the sensitive parameters
See Also:
org.owasp.esapi.Logger#logHTTPRequest(org.owasp.esapi.Logger,java.util.List)
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/DefaultIntrusionDetector.html b/javadoc/org/owasp/esapi/reference/DefaultIntrusionDetector.html deleted file mode 100644 index 5e8e757a0..000000000 --- a/javadoc/org/owasp/esapi/reference/DefaultIntrusionDetector.html +++ /dev/null @@ -1,311 +0,0 @@ - - - - - - -DefaultIntrusionDetector - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class DefaultIntrusionDetector

-
-java.lang.Object
-  extended byorg.owasp.esapi.reference.DefaultIntrusionDetector
-
-
-
All Implemented Interfaces:
IntrusionDetector
-
-
-
-
public class DefaultIntrusionDetector
extends java.lang.Object
implements IntrusionDetector
- -

-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
-
See Also:
IntrusionDetector
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
DefaultIntrusionDetector() - -
-           
-  - - - - - - - - - - - - - - - -
-Method Summary
- voidaddEvent(java.lang.String eventName, - java.lang.String logMessage) - -
-          Adds the event to the IntrusionDetector.
- voidaddException(java.lang.Exception e) - -
-          This implementation uses an exception store in each User object to track - exceptions.
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-DefaultIntrusionDetector

-
-public DefaultIntrusionDetector()
-
-
- - - - - - - - -
-Method Detail
- -

-addException

-
-public void addException(java.lang.Exception e)
-
-
This implementation uses an exception store in each User object to track - exceptions. -

-

-
Specified by:
addException in interface IntrusionDetector
-
-
-
Parameters:
e - the e -
Throws: -
IntrusionException - the intrusion exception
See Also:
org.owasp.esapi.IntrusionDetector#addException(org.owasp.esapi.errors.EnterpriseSecurityException)
-
-
-
- -

-addEvent

-
-public void addEvent(java.lang.String eventName,
-                     java.lang.String logMessage)
-              throws IntrusionException
-
-
Adds the event to the IntrusionDetector. -

-

-
Specified by:
addEvent in interface IntrusionDetector
-
-
-
Parameters:
logMessage - the message to log
eventName - the event -
Throws: -
IntrusionException - the intrusion exception
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/DefaultRandomizer.html b/javadoc/org/owasp/esapi/reference/DefaultRandomizer.html deleted file mode 100644 index aeeb1ebb3..000000000 --- a/javadoc/org/owasp/esapi/reference/DefaultRandomizer.html +++ /dev/null @@ -1,437 +0,0 @@ - - - - - - -DefaultRandomizer - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class DefaultRandomizer

-
-java.lang.Object
-  extended byorg.owasp.esapi.reference.DefaultRandomizer
-
-
-
All Implemented Interfaces:
Randomizer
-
-
-
-
public class DefaultRandomizer
extends java.lang.Object
implements Randomizer
- -

-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
-
See Also:
Randomizer
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
DefaultRandomizer() - -
-          Hide the constructor for the Singleton pattern.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- booleangetRandomBoolean() - -
-          Returns a random boolean.
- java.lang.StringgetRandomFilename(java.lang.String extension) - -
-          Returns an unguessable random filename with the specified extension.
- java.lang.StringgetRandomGUID() - -
-          Generates a random GUID.
- intgetRandomInteger(int min, - int max) - -
-          (non-Javadoc)
- longgetRandomLong() - -
-          (non-Javadoc)
- floatgetRandomReal(float min, - float max) - -
-          Gets the random real.
- java.lang.StringgetRandomString(int length, - char[] characterSet) - -
-          Gets a random string.
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-DefaultRandomizer

-
-public DefaultRandomizer()
-
-
Hide the constructor for the Singleton pattern. -

-

- - - - - - - - -
-Method Detail
- -

-getRandomString

-
-public java.lang.String getRandomString(int length,
-                                        char[] characterSet)
-
-
Description copied from interface: Randomizer
-
Gets a random string. of a desired length and character set. -

-

-
Specified by:
getRandomString in interface Randomizer
-
-
-
Parameters:
length - the length of the string
characterSet - the character set -
Returns:
the random string
-
-
-
- -

-getRandomBoolean

-
-public boolean getRandomBoolean()
-
-
Description copied from interface: Randomizer
-
Returns a random boolean. -

-

-
Specified by:
getRandomBoolean in interface Randomizer
-
-
- -
Returns:
true or false, randomly
-
-
-
- -

-getRandomInteger

-
-public int getRandomInteger(int min,
-                            int max)
-
-
(non-Javadoc) -

-

-
Specified by:
getRandomInteger in interface Randomizer
-
-
-
Parameters:
min - the minimum integer that will be returned
max - the maximum integer that will be returned -
Returns:
the random integer
See Also:
Randomizer.getRandomInteger(int, int)
-
-
-
- -

-getRandomLong

-
-public long getRandomLong()
-
-
(non-Javadoc) -

-

-
Specified by:
getRandomLong in interface Randomizer
-
-
- -
Returns:
the random long
See Also:
Randomizer.getRandomLong()
-
-
-
- -

-getRandomReal

-
-public float getRandomReal(float min,
-                           float max)
-
-
Description copied from interface: Randomizer
-
Gets the random real. -

-

-
Specified by:
getRandomReal in interface Randomizer
-
-
-
Parameters:
min - the minimum real number that will be returned
max - the maximum real number that will be returned -
Returns:
the random real
-
-
-
- -

-getRandomFilename

-
-public java.lang.String getRandomFilename(java.lang.String extension)
-
-
Returns an unguessable random filename with the specified extension. -

-

-
Specified by:
getRandomFilename in interface Randomizer
-
-
- -
Returns:
a random unguessable filename ending with the specified extension
-
-
-
- -

-getRandomGUID

-
-public java.lang.String getRandomGUID()
-                               throws EncryptionException
-
-
Description copied from interface: Randomizer
-
Generates a random GUID. -

-

-
Specified by:
getRandomGUID in interface Randomizer
-
-
- -
Returns:
the GUID -
Throws: -
EncryptionException
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/DefaultSafeFile.html b/javadoc/org/owasp/esapi/reference/DefaultSafeFile.html deleted file mode 100644 index c88cfd1de..000000000 --- a/javadoc/org/owasp/esapi/reference/DefaultSafeFile.html +++ /dev/null @@ -1,308 +0,0 @@ - - - - - - -DefaultSafeFile - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class DefaultSafeFile

-
-java.lang.Object
-  extended byjava.io.File
-      extended byorg.owasp.esapi.reference.DefaultSafeFile
-
-
-
All Implemented Interfaces:
java.lang.Comparable, java.io.Serializable
-
-
-
-
public class DefaultSafeFile
extends java.io.File
- -

-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. -

- -

-

-
See Also:
Serialized Form
-
- -

- - - - - - - - - - -
-Field Summary
- - - - - - - -
Fields inherited from class java.io.File
pathSeparator, pathSeparatorChar, separator, separatorChar
-  - - - - - - - - - - - - - - - - - - - -
-Constructor Summary
DefaultSafeFile(java.io.File parent, - java.lang.String child) - -
-           
DefaultSafeFile(java.lang.String path) - -
-           
DefaultSafeFile(java.lang.String parent, - java.lang.String child) - -
-           
DefaultSafeFile(java.net.URI uri) - -
-           
-  - - - - - - - - - - -
Methods inherited from class java.io.File
canRead, canWrite, compareTo, compareTo, createNewFile, createTempFile, createTempFile, delete, deleteOnExit, equals, exists, getAbsoluteFile, getAbsolutePath, getCanonicalFile, getCanonicalPath, getName, getParent, getParentFile, getPath, hashCode, isAbsolute, isDirectory, isFile, isHidden, lastModified, length, list, list, listFiles, listFiles, listFiles, listRoots, mkdir, mkdirs, renameTo, setLastModified, setReadOnly, toString, toURI, toURL
- - - - - - - -
Methods inherited from class java.lang.Object
getClass, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-DefaultSafeFile

-
-public DefaultSafeFile(java.lang.String path)
-                throws ValidationException
-
-
-
- -

-DefaultSafeFile

-
-public DefaultSafeFile(java.lang.String parent,
-                       java.lang.String child)
-                throws ValidationException
-
-
-
- -

-DefaultSafeFile

-
-public DefaultSafeFile(java.io.File parent,
-                       java.lang.String child)
-                throws ValidationException
-
-
-
- -

-DefaultSafeFile

-
-public DefaultSafeFile(java.net.URI uri)
-                throws ValidationException
-
-
- - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/DefaultSecurityConfiguration.html b/javadoc/org/owasp/esapi/reference/DefaultSecurityConfiguration.html deleted file mode 100644 index 9af2337a6..000000000 --- a/javadoc/org/owasp/esapi/reference/DefaultSecurityConfiguration.html +++ /dev/null @@ -1,899 +0,0 @@ - - - - - - -DefaultSecurityConfiguration - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class DefaultSecurityConfiguration

-
-java.lang.Object
-  extended byorg.owasp.esapi.reference.DefaultSecurityConfiguration
-
-
-
All Implemented Interfaces:
SecurityConfiguration
-
-
-
-
public class DefaultSecurityConfiguration
extends java.lang.Object
implements SecurityConfiguration
- -

-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: - -

- 
- java -Dorg.owasp.esapi.resources="C:\temp\resources"
- 
- 
- - 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. -

- -

-

-
Author:
-
jwilliams
-
-
- -

- - - - - - - -
-Nested Class Summary
- - - - - - - -
Nested classes inherited from class org.owasp.esapi.SecurityConfiguration
SecurityConfiguration.Threshold
-  - - - - - - - - - - - -
-Field Summary
-static java.lang.StringRESOURCE_DIRECTORY - -
-           
-  - - - - - - - - - - -
-Constructor Summary
DefaultSecurityConfiguration() - -
-          Instantiates a new configuration.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- java.util.ListgetAllowedFileExtensions() - -
-          Gets the allowed file extensions.
- intgetAllowedFileUploadSize() - -
-          Gets the allowed file upload size.
- intgetAllowedLoginAttempts() - -
-          Gets the allowed login attempts.
- java.lang.StringgetApplicationName() - -
-          Gets the application name, used for logging
- java.lang.StringgetCharacterEncoding() - -
-          Gets the character encoding.
- java.lang.StringgetDigitalSignatureAlgorithm() - -
-          Gets the digital signature algorithm.
- java.lang.StringgetEncryptionAlgorithm() - -
-          Gets the encryption algorithm.
- java.lang.StringgetHashAlgorithm() - -
-          Gets the hasing algorithm.
- java.io.FilegetKeystore() - -
-          Gets the keystore.
- booleangetLogEncodingRequired() - -
-          Returns whether HTML entity encoding should be applied to log entries.
- java.util.logging.LevelgetLogLevel() - -
-           
- char[]getMasterPassword() - -
-          Gets the master password.
- byte[]getMasterSalt() - -
-          Gets the master salt.
- intgetMaxOldPasswordHashes() - -
-          Gets the max old password hashes.
- java.lang.StringgetPasswordParameterName() - -
-          Gets the password parameter name.
- SecurityConfiguration.ThresholdgetQuota(java.lang.String eventName) - -
-          Gets an intrusion detection Quota.
- java.lang.StringgetRandomAlgorithm() - -
-          Gets the random number generation algorithm.
- longgetRememberTokenDuration() - -
-          Gets the time window allowed for the remember token in milliseconds.
- java.lang.StringgetResourceDirectory() - -
-          Gets the resource directory.
- java.lang.StringgetResponseContentType() - -
-          Gets the content-type set for responses.
- java.lang.StringgetUsernameParameterName() - -
-          Gets the username parameter name.
- java.util.regex.PatterngetValidationPattern(java.lang.String key) - -
-           
- java.util.IteratorgetValidationPatternNames() - -
-           
- voidsetResourceDirectory(java.lang.String dir) - -
-          Sets the ESAPI resource directory.
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - -
-Field Detail
- -

-RESOURCE_DIRECTORY

-
-public static final java.lang.String RESOURCE_DIRECTORY
-
-
-
See Also:
Constant Field Values
-
- - - - - - - - -
-Constructor Detail
- -

-DefaultSecurityConfiguration

-
-public DefaultSecurityConfiguration()
-
-
Instantiates a new configuration. -

-

- - - - - - - - -
-Method Detail
- -

-getApplicationName

-
-public java.lang.String getApplicationName()
-
-
Description copied from interface: SecurityConfiguration
-
Gets the application name, used for logging -

-

-
Specified by:
getApplicationName in interface SecurityConfiguration
-
-
- -
Returns:
the application name
-
-
-
- -

-getMasterPassword

-
-public char[] getMasterPassword()
-
-
Gets the master password. -

-

-
Specified by:
getMasterPassword in interface SecurityConfiguration
-
-
- -
Returns:
the master password
-
-
-
- -

-getKeystore

-
-public java.io.File getKeystore()
-
-
Gets the keystore. -

-

-
Specified by:
getKeystore in interface SecurityConfiguration
-
-
- -
Returns:
the keystore
-
-
-
- -

-getResourceDirectory

-
-public java.lang.String getResourceDirectory()
-
-
Gets the resource directory. -

-

-
Specified by:
getResourceDirectory in interface SecurityConfiguration
-
-
- -
Returns:
the resource directory
-
-
-
- -

-setResourceDirectory

-
-public void setResourceDirectory(java.lang.String dir)
-
-
Description copied from interface: SecurityConfiguration
-
Sets the ESAPI resource directory. -

-

-
Specified by:
setResourceDirectory in interface SecurityConfiguration
-
-
-
Parameters:
dir - location of the resource directory
-
-
-
- -

-getMasterSalt

-
-public byte[] getMasterSalt()
-
-
Gets the master salt. -

-

-
Specified by:
getMasterSalt in interface SecurityConfiguration
-
-
- -
Returns:
the master salt
-
-
-
- -

-getAllowedFileExtensions

-
-public java.util.List getAllowedFileExtensions()
-
-
Gets the allowed file extensions. -

-

-
Specified by:
getAllowedFileExtensions in interface SecurityConfiguration
-
-
- -
Returns:
the allowed file extensions
-
-
-
- -

-getAllowedFileUploadSize

-
-public int getAllowedFileUploadSize()
-
-
Gets the allowed file upload size. -

-

-
Specified by:
getAllowedFileUploadSize in interface SecurityConfiguration
-
-
- -
Returns:
the allowed file upload size
-
-
-
- -

-getPasswordParameterName

-
-public java.lang.String getPasswordParameterName()
-
-
Gets the password parameter name. -

-

-
Specified by:
getPasswordParameterName in interface SecurityConfiguration
-
-
- -
Returns:
the password parameter name
-
-
-
- -

-getUsernameParameterName

-
-public java.lang.String getUsernameParameterName()
-
-
Gets the username parameter name. -

-

-
Specified by:
getUsernameParameterName in interface SecurityConfiguration
-
-
- -
Returns:
the username parameter name
-
-
-
- -

-getEncryptionAlgorithm

-
-public java.lang.String getEncryptionAlgorithm()
-
-
Gets the encryption algorithm. -

-

-
Specified by:
getEncryptionAlgorithm in interface SecurityConfiguration
-
-
- -
Returns:
the algorithm
-
-
-
- -

-getHashAlgorithm

-
-public java.lang.String getHashAlgorithm()
-
-
Gets the hasing algorithm. -

-

-
Specified by:
getHashAlgorithm in interface SecurityConfiguration
-
-
- -
Returns:
the algorithm
-
-
-
- -

-getCharacterEncoding

-
-public java.lang.String getCharacterEncoding()
-
-
Gets the character encoding. -

-

-
Specified by:
getCharacterEncoding in interface SecurityConfiguration
-
-
- -
Returns:
encoding name
-
-
-
- -

-getDigitalSignatureAlgorithm

-
-public java.lang.String getDigitalSignatureAlgorithm()
-
-
Gets the digital signature algorithm. -

-

-
Specified by:
getDigitalSignatureAlgorithm in interface SecurityConfiguration
-
-
- -
Returns:
encoding name
-
-
-
- -

-getRandomAlgorithm

-
-public java.lang.String getRandomAlgorithm()
-
-
Gets the random number generation algorithm. -

-

-
Specified by:
getRandomAlgorithm in interface SecurityConfiguration
-
-
- -
Returns:
encoding name
-
-
-
- -

-getAllowedLoginAttempts

-
-public int getAllowedLoginAttempts()
-
-
Gets the allowed login attempts. -

-

-
Specified by:
getAllowedLoginAttempts in interface SecurityConfiguration
-
-
- -
Returns:
the allowed login attempts
-
-
-
- -

-getMaxOldPasswordHashes

-
-public int getMaxOldPasswordHashes()
-
-
Gets the max old password hashes. -

-

-
Specified by:
getMaxOldPasswordHashes in interface SecurityConfiguration
-
-
- -
Returns:
the max old password hashes
-
-
-
- -

-getQuota

-
-public SecurityConfiguration.Threshold getQuota(java.lang.String eventName)
-
-
Description copied from interface: SecurityConfiguration
-
Gets an intrusion detection Quota. -

-

-
Specified by:
getQuota in interface SecurityConfiguration
-
-
-
Parameters:
eventName - the event whose quota is desired -
Returns:
the matching Quota for eventName
-
-
-
- -

-getLogLevel

-
-public java.util.logging.Level getLogLevel()
-
-
-
-
-
-
-
-
-
- -

-getResponseContentType

-
-public java.lang.String getResponseContentType()
-
-
Description copied from interface: SecurityConfiguration
-
Gets the content-type set for responses. -

-

-
Specified by:
getResponseContentType in interface SecurityConfiguration
-
-
-
-
-
-
- -

-getRememberTokenDuration

-
-public long getRememberTokenDuration()
-
-
Description copied from interface: SecurityConfiguration
-
Gets the time window allowed for the remember token in milliseconds. -

-

-
Specified by:
getRememberTokenDuration in interface SecurityConfiguration
-
-
-
-
-
-
- -

-getValidationPatternNames

-
-public java.util.Iterator getValidationPatternNames()
-
-
-
-
-
-
-
-
-
- -

-getValidationPattern

-
-public java.util.regex.Pattern getValidationPattern(java.lang.String key)
-
-
-
-
-
-
-
-
-
- -

-getLogEncodingRequired

-
-public boolean getLogEncodingRequired()
-
-
Description copied from interface: SecurityConfiguration
-
Returns whether HTML entity encoding should be applied to log entries. -

-

-
Specified by:
getLogEncodingRequired in interface SecurityConfiguration
-
-
-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/DefaultUser.html b/javadoc/org/owasp/esapi/reference/DefaultUser.html deleted file mode 100644 index 04812445e..000000000 --- a/javadoc/org/owasp/esapi/reference/DefaultUser.html +++ /dev/null @@ -1,1352 +0,0 @@ - - - - - - -DefaultUser - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class DefaultUser

-
-java.lang.Object
-  extended byorg.owasp.esapi.reference.DefaultUser
-
-
-
All Implemented Interfaces:
java.security.Principal, java.io.Serializable, User
-
-
-
-
public class DefaultUser
extends java.lang.Object
implements User, java.io.Serializable
- -

-Reference implementation of the User interface. This implementation is serialized into a flat file in a simple format. -

- -

-

-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
-
See Also:
User, -Serialized Form
-
- -

- - - - - - - - - - -
-Field Summary
- - - - - - - -
Fields inherited from interface org.owasp.esapi.User
ANONYMOUS
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- voidaddRole(java.lang.String role) - -
-          Adds a role to an account.
- voidaddRoles(java.util.Set newRoles) - -
-          Adds a set of roles to an account.
- voidchangePassword(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.Objectclone() - -
-          Override clone and make final to prevent duplicate user objects.
- voiddisable() - -
-          Disable account.
- voidenable() - -
-          Enable the account
- longgetAccountId() - -
-          Gets the account id.
- java.lang.StringgetAccountName() - -
-          Gets the account name.
- java.lang.StringgetCSRFToken() - -
-          Gets the CSRF token.
- java.util.DategetExpirationTime() - -
-          Gets the expiration time.
- intgetFailedLoginCount() - -
-          Gets the failed login count.
- java.util.DategetLastFailedLoginTime() - -
-          Gets the last failed login time.
- java.lang.StringgetLastHostAddress() - -
-          Returns the last host address used by the user.
- java.util.DategetLastLoginTime() - -
-          Gets the last login time.
- java.util.DategetLastPasswordChangeTime() - -
-          Gets the last password change time.
- java.lang.StringgetName() - -
-           
- java.util.SetgetRoles() - -
-          Gets the roles.
- java.lang.StringgetScreenName() - -
-          Gets the screen name.
- voidincrementFailedLoginCount() - -
-          Increment failed login count.
- booleanisAnonymous() - -
-          Checks if user is anonymous.
- booleanisEnabled() - -
-          Checks if is enabled.
- booleanisExpired() - -
-          Checks if an account is expired.
- booleanisInRole(java.lang.String role) - -
-          Checks if an account has been assigned a particular role.
- booleanisLocked() - -
-          Checks if an account is locked.
- booleanisLoggedIn() - -
-          Tests to see if the user is currently logged in.
- booleanisSessionAbsoluteTimeout() - -
-          Tests to see if the user's session has exceeded the absolute time out.
- booleanisSessionTimeout() - -
-          Tests to see if the user's session has timed out from inactivity.
- voidlock() - -
-          Lock the user's account.
- voidloginWithPassword(java.lang.String password) - -
-          Login with password.
- voidlogout() - -
-          Logout this user.
- voidremoveRole(java.lang.String role) - -
-          Removes a role from an account.
- java.lang.StringresetCSRFToken() - -
-          In this implementation, we have chosen to use a random token that is - stored in the User object.
- voidsetAccountName(java.lang.String accountName) - -
-          Sets the account name.
- voidsetExpirationTime(java.util.Date expirationTime) - -
-          Sets the expiration time.
- voidsetLastFailedLoginTime(java.util.Date lastFailedLoginTime) - -
-          Sets the last failed login time.
- voidsetLastHostAddress(java.lang.String remoteHost) - -
-          Sets the last remote host address used by this User.
- voidsetLastLoginTime(java.util.Date lastLoginTime) - -
-          Sets the last login time.
- voidsetLastPasswordChangeTime(java.util.Date lastPasswordChangeTime) - -
-          Sets the last password change time.
- voidsetRoles(java.util.Set roles) - -
-          Sets the roles.
- voidsetScreenName(java.lang.String screenName) - -
-          Sets the screen name.
- java.lang.StringtoString() - -
-           
- voidunlock() - -
-          Unlock account.
- booleanverifyPassword(java.lang.String password) - -
-          Verify that the supplied password matches the password for this user.
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
- - - - - - - -
Methods inherited from interface java.security.Principal
equals, hashCode
-  -

- - - - - - - - - - - - - - -
-Method Detail
- -

-addRole

-
-public void addRole(java.lang.String role)
-             throws AuthenticationException
-
-
Description copied from interface: User
-
Adds a role to an account. -

-

-
Specified by:
addRole in interface User
-
-
-
Parameters:
role - the role to add -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-addRoles

-
-public void addRoles(java.util.Set newRoles)
-              throws AuthenticationException
-
-
Description copied from interface: User
-
Adds a set of roles to an account. -

-

-
Specified by:
addRoles in interface User
-
-
-
Parameters:
newRoles - the new roles to add -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-changePassword

-
-public void changePassword(java.lang.String oldPassword,
-                           java.lang.String newPassword1,
-                           java.lang.String newPassword2)
-                    throws AuthenticationException,
-                           EncryptionException
-
-
Description copied from interface: User
-
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. -

-

-
Specified by:
changePassword in interface User
-
-
-
Parameters:
oldPassword - the old password
newPassword1 - the new password
newPassword2 - the new password - used to verify that the new password was typed correctly -
Throws: -
EncryptionException -
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
-
-
-
- -

-disable

-
-public void disable()
-
-
Description copied from interface: User
-
Disable account. -

-

-
Specified by:
disable in interface User
-
-
-
-
-
-
- -

-enable

-
-public void enable()
-
-
Enable the account -

-

-
Specified by:
enable in interface User
-
-
-
See Also:
User.enable()
-
-
-
- -

-getAccountId

-
-public long getAccountId()
-
-
Description copied from interface: User
-
Gets the account id. -

-

-
Specified by:
getAccountId in interface User
-
-
- -
Returns:
the account id
-
-
-
- -

-getAccountName

-
-public java.lang.String getAccountName()
-
-
Gets the account name. -

-

-
Specified by:
getAccountName in interface User
-
-
- -
Returns:
the accountName
-
-
-
- -

-getCSRFToken

-
-public java.lang.String getCSRFToken()
-
-
Gets the CSRF token. Use the HTTPUtilities.checkCSRFToken( request ) to verify the token. -

-

-
Specified by:
getCSRFToken in interface User
-
-
- -
Returns:
the csrfToken
-
-
-
- -

-getExpirationTime

-
-public java.util.Date getExpirationTime()
-
-
Gets the expiration time. -

-

-
Specified by:
getExpirationTime in interface User
-
-
- -
Returns:
The expiration time of the current user.
-
-
-
- -

-getFailedLoginCount

-
-public int getFailedLoginCount()
-
-
Gets the failed login count. -

-

-
Specified by:
getFailedLoginCount in interface User
-
-
- -
Returns:
the failedLoginCount
-
-
-
- -

-getLastFailedLoginTime

-
-public java.util.Date getLastFailedLoginTime()
-
-
Gets the last failed login time. -

-

-
Specified by:
getLastFailedLoginTime in interface User
-
-
- -
Returns:
the lastFailedLoginTime
-
-
-
- -

-getLastHostAddress

-
-public java.lang.String getLastHostAddress()
-
-
Description copied from interface: User
-
Returns the last host address used by the user. This will be used in any log messages generated by the processing - of this request. -

-

-
Specified by:
getLastHostAddress in interface User
-
-
- -
Returns:
the last host address used by the user
-
-
-
- -

-getLastLoginTime

-
-public java.util.Date getLastLoginTime()
-
-
Gets the last login time. -

-

-
Specified by:
getLastLoginTime in interface User
-
-
- -
Returns:
the lastLoginTime
-
-
-
- -

-getLastPasswordChangeTime

-
-public java.util.Date getLastPasswordChangeTime()
-
-
Gets the last password change time. -

-

-
Specified by:
getLastPasswordChangeTime in interface User
-
-
- -
Returns:
the lastPasswordChangeTime
-
-
-
- -

-getName

-
-public java.lang.String getName()
-
-
-
Specified by:
getName in interface java.security.Principal
-
-
-
-
-
-
- -

-getRoles

-
-public java.util.Set getRoles()
-
-
Gets the roles. -

-

-
Specified by:
getRoles in interface User
-
-
- -
Returns:
the roles
-
-
-
- -

-getScreenName

-
-public java.lang.String getScreenName()
-
-
Description copied from interface: User
-
Gets the screen name. -

-

-
Specified by:
getScreenName in interface User
-
-
- -
Returns:
the screen name
-
-
-
- -

-incrementFailedLoginCount

-
-public void incrementFailedLoginCount()
-
-
Description copied from interface: User
-
Increment failed login count. -

-

-
Specified by:
incrementFailedLoginCount in interface User
-
-
-
-
-
-
- -

-isAnonymous

-
-public boolean isAnonymous()
-
-
Description copied from interface: User
-
Checks if user is anonymous. -

-

-
Specified by:
isAnonymous in interface User
-
-
- -
Returns:
true, if user is anonymous
-
-
-
- -

-isEnabled

-
-public boolean isEnabled()
-
-
Checks if is enabled. -

-

-
Specified by:
isEnabled in interface User
-
-
- -
Returns:
the enabled
-
-
-
- -

-isExpired

-
-public boolean isExpired()
-
-
Description copied from interface: User
-
Checks if an account is expired. -

-

-
Specified by:
isExpired in interface User
-
-
- -
Returns:
true, if account is expired
-
-
-
- -

-isInRole

-
-public boolean isInRole(java.lang.String role)
-
-
Description copied from interface: User
-
Checks if an account has been assigned a particular role. -

-

-
Specified by:
isInRole in interface User
-
-
-
Parameters:
role - the role for which to check -
Returns:
true, if role has been assigned to user
-
-
-
- -

-isLocked

-
-public boolean isLocked()
-
-
Description copied from interface: User
-
Checks if an account is locked. -

-

-
Specified by:
isLocked in interface User
-
-
- -
Returns:
true, if account is locked
-
-
-
- -

-isLoggedIn

-
-public boolean isLoggedIn()
-
-
Description copied from interface: User
-
Tests to see if the user is currently logged in. -

-

-
Specified by:
isLoggedIn in interface User
-
-
- -
Returns:
true, if the user is logged in
-
-
-
- -

-isSessionAbsoluteTimeout

-
-public boolean isSessionAbsoluteTimeout()
-
-
Description copied from interface: User
-
Tests to see if the user's session has exceeded the absolute time out. -

-

-
Specified by:
isSessionAbsoluteTimeout in interface User
-
-
- -
Returns:
true, if user's session has exceeded the absolute time out
-
-
-
- -

-isSessionTimeout

-
-public boolean isSessionTimeout()
-
-
Description copied from interface: User
-
Tests to see if the user's session has timed out from inactivity. -

-

-
Specified by:
isSessionTimeout in interface User
-
-
- -
Returns:
true, if user's session has timed out from inactivity
-
-
-
- -

-lock

-
-public void lock()
-
-
Description copied from interface: User
-
Lock the user's account. -

-

-
Specified by:
lock in interface User
-
-
-
-
-
-
- -

-loginWithPassword

-
-public void loginWithPassword(java.lang.String password)
-                       throws AuthenticationException
-
-
Description copied from interface: User
-
Login with password. -

-

-
Specified by:
loginWithPassword in interface User
-
-
-
Parameters:
password - the password -
Throws: -
AuthenticationException - if login fails
-
-
-
- -

-logout

-
-public void logout()
-
-
Description copied from interface: User
-
Logout this user. -

-

-
Specified by:
logout in interface User
-
-
-
-
-
-
- -

-removeRole

-
-public void removeRole(java.lang.String role)
-
-
Description copied from interface: User
-
Removes a role from an account. -

-

-
Specified by:
removeRole in interface User
-
-
-
Parameters:
role - the role to remove
-
-
-
- -

-resetCSRFToken

-
-public java.lang.String resetCSRFToken()
-
-
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. -

-

-
Specified by:
resetCSRFToken in interface User
-
-
- -
Returns:
the string
See Also:
User.resetCSRFToken()
-
-
-
- -

-setAccountName

-
-public void setAccountName(java.lang.String accountName)
-
-
Sets the account name. -

-

-
Specified by:
setAccountName in interface User
-
-
-
Parameters:
accountName - the accountName to set
-
-
-
- -

-setExpirationTime

-
-public void setExpirationTime(java.util.Date expirationTime)
-
-
Sets the expiration time. -

-

-
Specified by:
setExpirationTime in interface User
-
-
-
Parameters:
expirationTime - the expirationTime to set
-
-
-
- -

-setLastFailedLoginTime

-
-public void setLastFailedLoginTime(java.util.Date lastFailedLoginTime)
-
-
Sets the last failed login time. -

-

-
Specified by:
setLastFailedLoginTime in interface User
-
-
-
Parameters:
lastFailedLoginTime - the lastFailedLoginTime to set
-
-
-
- -

-setLastHostAddress

-
-public void setLastHostAddress(java.lang.String remoteHost)
-
-
Sets the last remote host address used by this User. -

-

-
Specified by:
setLastHostAddress in interface User
-
-
-
Parameters:
remoteHost -
-
-
-
- -

-setLastLoginTime

-
-public void setLastLoginTime(java.util.Date lastLoginTime)
-
-
Sets the last login time. -

-

-
Specified by:
setLastLoginTime in interface User
-
-
-
Parameters:
lastLoginTime - the lastLoginTime to set
-
-
-
- -

-setLastPasswordChangeTime

-
-public void setLastPasswordChangeTime(java.util.Date lastPasswordChangeTime)
-
-
Sets the last password change time. -

-

-
Specified by:
setLastPasswordChangeTime in interface User
-
-
-
Parameters:
lastPasswordChangeTime - the lastPasswordChangeTime to set
-
-
-
- -

-setRoles

-
-public void setRoles(java.util.Set roles)
-              throws AuthenticationException
-
-
Sets the roles. -

-

-
Specified by:
setRoles in interface User
-
-
-
Parameters:
roles - the roles to set -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-setScreenName

-
-public void setScreenName(java.lang.String screenName)
-
-
Description copied from interface: User
-
Sets the screen name. -

-

-
Specified by:
setScreenName in interface User
-
-
-
Parameters:
screenName - the new screen name
-
-
-
- -

-toString

-
-public java.lang.String toString()
-
-
-
Specified by:
toString in interface java.security.Principal
-
-
-
-
-
-
- -

-unlock

-
-public void unlock()
-
-
Description copied from interface: User
-
Unlock account. -

-

-
Specified by:
unlock in interface User
-
-
-
-
-
-
- -

-verifyPassword

-
-public boolean verifyPassword(java.lang.String password)
-
-
Description copied from interface: User
-
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. -

-

-
Specified by:
verifyPassword in interface User
-
-
-
Parameters:
password - the password that the user entered -
Returns:
true, if the password passed in matches the account's password
-
-
-
- -

-clone

-
-public final java.lang.Object clone()
-                             throws java.lang.CloneNotSupportedException
-
-
Override clone and make final to prevent duplicate user objects. -

-

-
-
-
- -
Throws: -
java.lang.CloneNotSupportedException
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/DefaultValidator.html b/javadoc/org/owasp/esapi/reference/DefaultValidator.html deleted file mode 100644 index f3c0a33e0..000000000 --- a/javadoc/org/owasp/esapi/reference/DefaultValidator.html +++ /dev/null @@ -1,2130 +0,0 @@ - - - - - - -DefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class DefaultValidator

-
-java.lang.Object
-  extended byorg.owasp.esapi.reference.DefaultValidator
-
-
-
All Implemented Interfaces:
Validator
-
-
-
-
public class DefaultValidator
extends java.lang.Object
implements Validator
- -

-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

&lt;
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
-
See Also:
Validator
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
DefaultValidator() - -
-           
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- voidassertIsValidHTTPRequest() - -
-          Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed - characters.
- voidassertIsValidHTTPRequestParameterSet(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.
- voidassertIsValidHTTPRequestParameterSet(java.lang.String context, - java.util.Set required, - java.util.Set optional, - ValidationErrorList errors) - -
-          ValidationErrorList variant of assertIsValidHTTPRequestParameterSet
- voidassertValidFileUpload(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.
- voidassertValidFileUpload(java.lang.String context, - java.lang.String filepath, - java.lang.String filename, - byte[] content, - int maxBytes, - boolean allowNull, - ValidationErrorList errors) - -
-          ValidationErrorList variant of assertValidFileUpload
- java.lang.StringgetValidCreditCard(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated credit card number as a String.
- java.lang.StringgetValidCreditCard(java.lang.String context, - java.lang.String input, - boolean allowNull, - ValidationErrorList errors) - -
-          ValidationErrorList variant of getValidCreditCard
- java.util.DategetValidDate(java.lang.String context, - java.lang.String input, - java.text.DateFormat format, - boolean allowNull) - -
-          Returns a valid date as a Date.
- java.util.DategetValidDate(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.StringgetValidDirectoryPath(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated directory path as a String.
- java.lang.StringgetValidDirectoryPath(java.lang.String context, - java.lang.String input, - boolean allowNull, - ValidationErrorList errors) - -
-          ValidationErrorList variant of getValidDirectoryPath
- java.lang.DoublegetValidDouble(java.lang.String context, - java.lang.String input, - double minValue, - double maxValue, - boolean allowNull) - -
-          Returns a validated number as a double.
- java.lang.DoublegetValidDouble(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.StringgetValidFileName(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated file name as a String.
- java.lang.StringgetValidFileName(java.lang.String context, - java.lang.String input, - boolean allowNull, - ValidationErrorList errors) - -
-          Returns a canonicalized and validated file name as a String.
- java.lang.StringgetValidInput(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.StringgetValidInput(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.IntegergetValidInteger(java.lang.String context, - java.lang.String input, - int minValue, - int maxValue, - boolean allowNull) - -
-          Returns a validated number as a double.
- java.lang.IntegergetValidInteger(java.lang.String context, - java.lang.String input, - int minValue, - int maxValue, - boolean allowNull, - ValidationErrorList errors) - -
-          Returns a validated integer.
- java.lang.StringgetValidListItem(java.lang.String context, - java.lang.String input, - java.util.List list) - -
-          Returns the list item that exactly matches the canonicalized input.
- java.lang.StringgetValidListItem(java.lang.String context, - java.lang.String input, - java.util.List list, - ValidationErrorList errors) - -
-          ValidationErrorList variant of getValidListItem
- java.lang.DoublegetValidNumber(java.lang.String context, - java.lang.String input, - long minValue, - long maxValue, - boolean allowNull) - -
-          Returns a validated number as a double.
- java.lang.DoublegetValidNumber(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.
- byte[]getValidPrintable(java.lang.String context, - byte[] input, - int maxLength, - boolean allowNull, - ValidationErrorList errors) - -
-          ValidationErrorList variant of getValidPrintable
- java.lang.StringgetValidPrintable(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-          Returns canonicalized and validated printable characters as a String.
- java.lang.StringgetValidPrintable(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull, - ValidationErrorList errors) - -
-          ValidationErrorList variant of getValidPrintable
- java.lang.StringgetValidRedirectLocation(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns a canonicalized and validated redirect location as a String.
- java.lang.StringgetValidRedirectLocation(java.lang.String context, - java.lang.String input, - boolean allowNull, - ValidationErrorList errors) - -
-          ValidationErrorList variant of getValidRedirectLocation
- java.lang.StringgetValidSafeHTML(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-          Returns canonicalized and validated "safe" HTML.
- java.lang.StringgetValidSafeHTML(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull, - ValidationErrorList errors) - -
-          ValidationErrorList variant of getValidSafeHTML
- booleanisValidCreditCard(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns true if input is a valid credit card.
- booleanisValidDate(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.
- booleanisValidDirectoryPath(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns true if the directory path (not including a filename) is valid.
- booleanisValidDouble(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.
- booleanisValidFileContent(java.lang.String context, - byte[] input, - int maxBytes, - boolean allowNull) - -
-          Returns true if input is valid file content.
- booleanisValidFileName(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns true if input is a valid file name.
- booleanisValidFileUpload(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.
- booleanisValidHTTPRequest() - -
-          Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed - characters.
- booleanisValidHTTPRequest(javax.servlet.http.HttpServletRequest request) - -
-          Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed - characters.
- booleanisValidHTTPRequestParameterSet(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.
- booleanisValidInput(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.
- booleanisValidInteger(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.
- booleanisValidListItem(java.lang.String context, - java.lang.String input, - java.util.List list) - -
-          Returns true if input is a valid list item.
- booleanisValidNumber(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.
- booleanisValidPrintable(java.lang.String context, - byte[] input, - int maxLength, - boolean allowNull) - -
-          Checks that all bytes are valid ASCII characters (between 33 and 126 - inclusive).
- booleanisValidPrintable(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-          Returns true if input contains only valid printable ASCII characters (32-126).
- booleanisValidRedirectLocation(java.lang.String context, - java.lang.String input, - boolean allowNull) - -
-          Returns true if input is a valid redirect location.
- booleanisValidSafeHTML(java.lang.String context, - java.lang.String input, - int maxLength, - boolean allowNull) - -
-          Returns true if input is "safe" HTML.
- java.lang.StringsafeReadLine(java.io.InputStream in, - int max) - -
-          This implementation reads until a newline or the specified number of - characters.
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-DefaultValidator

-
-public DefaultValidator()
-
-
- - - - - - - - -
-Method Detail
- -

-isValidInput

-
-public boolean isValidInput(java.lang.String context,
-                            java.lang.String input,
-                            java.lang.String type,
-                            int maxLength,
-                            boolean allowNull)
-                     throws IntrusionException
-
-
Returns true if data received from browser is valid. Only URL encoding is - supported. Double encoding is treated as an attack. -

-

-
Specified by:
isValidInput in interface Validator
-
-
-
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:
The canonicalized user input. -
Throws: -
IntrusionException
-
-
-
- -

-getValidInput

-
-public java.lang.String getValidInput(java.lang.String context,
-                                      java.lang.String input,
-                                      java.lang.String type,
-                                      int maxLength,
-                                      boolean allowNull)
-                               throws ValidationException,
-                                      IntrusionException
-
-
Validates data received from the browser and returns a safe version. Only - URL encoding is supported. Double encoding is treated as an attack. -

-

-
Specified by:
getValidInput in interface Validator
-
-
-
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:
The canonicalized user input. -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-getValidInput

-
-public java.lang.String getValidInput(java.lang.String context,
-                                      java.lang.String input,
-                                      java.lang.String type,
-                                      int maxLength,
-                                      boolean allowNull,
-                                      ValidationErrorList errors)
-                               throws IntrusionException
-
-
Validates data received from the browser and returns a safe version. Only - URL encoding is supported. Double encoding is treated as an attack. -

-

-
Specified by:
getValidInput in interface Validator
-
-
-
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.
errors - If ValidationException is thrown, then add to error list instead of throwing out to caller -
Returns:
The canonicalized user input. -
Throws: -
IntrusionException
-
-
-
- -

-isValidDate

-
-public boolean isValidDate(java.lang.String context,
-                           java.lang.String input,
-                           java.text.DateFormat format,
-                           boolean allowNull)
-                    throws IntrusionException
-
-
Returns true if input is a valid date according to the specified date format. -

-

-
Specified by:
isValidDate in interface Validator
-
-
-
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' -
Throws: -
IntrusionException
-
-
-
- -

-getValidDate

-
-public java.util.Date getValidDate(java.lang.String context,
-                                   java.lang.String input,
-                                   java.text.DateFormat format,
-                                   boolean allowNull)
-                            throws ValidationException,
-                                   IntrusionException
-
-
Description copied from interface: Validator
-
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. -

-

-
Specified by:
getValidDate in interface Validator
-
-
-
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 -
Throws: -
IntrusionException -
ValidationException
-
-
-
- -

-getValidDate

-
-public java.util.Date getValidDate(java.lang.String context,
-                                   java.lang.String input,
-                                   java.text.DateFormat format,
-                                   boolean allowNull,
-                                   ValidationErrorList errors)
-                            throws IntrusionException
-
-
Description copied from interface: Validator
-
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. -

-

-
Specified by:
getValidDate in interface Validator
-
-
-
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.
errors - If validation is in error, resulting error will be stored in the errorList by context -
Returns:
A valid date as a Date -
Throws: -
IntrusionException
-
-
-
- -

-isValidSafeHTML

-
-public boolean isValidSafeHTML(java.lang.String context,
-                               java.lang.String input,
-                               int maxLength,
-                               boolean allowNull)
-                        throws IntrusionException
-
-
Description copied from interface: Validator
-
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. -

-

-
Specified by:
isValidSafeHTML in interface Validator
-
-
-
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:
true, if input is valid safe HTML -
Throws: -
IntrusionException
-
-
-
- -

-getValidSafeHTML

-
-public java.lang.String getValidSafeHTML(java.lang.String context,
-                                         java.lang.String input,
-                                         int maxLength,
-                                         boolean allowNull)
-                                  throws ValidationException,
-                                         IntrusionException
-
-
Description copied from interface: Validator
-
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. -

-

-
Specified by:
getValidSafeHTML in interface Validator
-
-
-
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:
Valid safe HTML -
Throws: -
IntrusionException -
ValidationException
-
-
-
- -

-getValidSafeHTML

-
-public java.lang.String getValidSafeHTML(java.lang.String context,
-                                         java.lang.String input,
-                                         int maxLength,
-                                         boolean allowNull,
-                                         ValidationErrorList errors)
-                                  throws IntrusionException
-
-
ValidationErrorList variant of getValidSafeHTML -

-

-
Specified by:
getValidSafeHTML in interface Validator
-
-
-
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.
errors - If validation is in error, resulting error will be stored in the errorList by context -
Returns:
Valid safe HTML -
Throws: -
IntrusionException
-
-
-
- -

-isValidCreditCard

-
-public boolean isValidCreditCard(java.lang.String context,
-                                 java.lang.String input,
-                                 boolean allowNull)
-                          throws IntrusionException
-
-
Description copied from interface: Validator
-
Returns true if input is a valid credit card. Maxlength is mandated by valid credit card type. -

-

-
Specified by:
isValidCreditCard in interface Validator
-
-
-
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:
true, if input is a valid credit card number -
Throws: -
IntrusionException
-
-
-
- -

-getValidCreditCard

-
-public java.lang.String getValidCreditCard(java.lang.String context,
-                                           java.lang.String input,
-                                           boolean allowNull)
-                                    throws ValidationException,
-                                           IntrusionException
-
-
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. -

-

-
Specified by:
getValidCreditCard in interface Validator
-
-
-
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 valid credit card number -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-getValidCreditCard

-
-public java.lang.String getValidCreditCard(java.lang.String context,
-                                           java.lang.String input,
-                                           boolean allowNull,
-                                           ValidationErrorList errors)
-                                    throws IntrusionException
-
-
ValidationErrorList variant of getValidCreditCard -

-

-
Specified by:
getValidCreditCard in interface Validator
-
-
-
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.
errors - If validation is in error, resulting error will be stored in the errorList by context -
Returns:
A valid credit card number -
Throws: -
IntrusionException
-
-
-
- -

-isValidDirectoryPath

-
-public boolean isValidDirectoryPath(java.lang.String context,
-                                    java.lang.String input,
-                                    boolean allowNull)
-                             throws IntrusionException
-
-
Returns true if the directory path (not including a filename) is valid. -

-

-
Specified by:
isValidDirectoryPath in interface Validator
-
-
-
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:
true, if input is a valid directory path -
Throws: -
IntrusionException
See Also:
org.owasp.esapi.Validator#isValidDirectoryPath(java.lang.String)
-
-
-
- -

-getValidDirectoryPath

-
-public java.lang.String getValidDirectoryPath(java.lang.String context,
-                                              java.lang.String input,
-                                              boolean allowNull)
-                                       throws ValidationException,
-                                              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. -

-

-
Specified by:
getValidDirectoryPath in interface Validator
-
-
-
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 valid directory path -
Throws: -
IntrusionException -
ValidationException
-
-
-
- -

-getValidDirectoryPath

-
-public java.lang.String getValidDirectoryPath(java.lang.String context,
-                                              java.lang.String input,
-                                              boolean allowNull,
-                                              ValidationErrorList errors)
-                                       throws IntrusionException
-
-
ValidationErrorList variant of getValidDirectoryPath -

-

-
Specified by:
getValidDirectoryPath in interface Validator
-
-
-
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.
errors - If validation is in error, resulting error will be stored in the errorList by context -
Returns:
A valid directory path -
Throws: -
IntrusionException
-
-
-
- -

-isValidFileName

-
-public boolean isValidFileName(java.lang.String context,
-                               java.lang.String input,
-                               boolean allowNull)
-                        throws IntrusionException
-
-
Returns true if input is a valid file name. -

-

-
Specified by:
isValidFileName in interface Validator
-
-
-
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:
true, if input is a valid file name -
Throws: -
IntrusionException
-
-
-
- -

-getValidFileName

-
-public java.lang.String getValidFileName(java.lang.String context,
-                                         java.lang.String input,
-                                         boolean allowNull)
-                                  throws ValidationException,
-                                         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. -

-

-
Specified by:
getValidFileName in interface Validator
-
-
-
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 valid file name -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-getValidFileName

-
-public java.lang.String getValidFileName(java.lang.String context,
-                                         java.lang.String input,
-                                         boolean allowNull,
-                                         ValidationErrorList errors)
-                                  throws 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. -

-

-
Specified by:
getValidFileName in interface Validator
-
-
-
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.
errors - If validation is in error, resulting error will be stored in the errorList by context -
Returns:
A valid file name -
Throws: -
IntrusionException
-
-
-
- -

-isValidNumber

-
-public boolean isValidNumber(java.lang.String context,
-                             java.lang.String input,
-                             long minValue,
-                             long maxValue,
-                             boolean allowNull)
-                      throws IntrusionException
-
-
Description copied from interface: Validator
-
Returns true if input is a valid number within the range of minValue to maxValue. -

-

-
Specified by:
isValidNumber in interface Validator
-
-
-
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:
true, if input is a valid number -
Throws: -
IntrusionException
-
-
-
- -

-getValidNumber

-
-public java.lang.Double getValidNumber(java.lang.String context,
-                                       java.lang.String input,
-                                       long minValue,
-                                       long maxValue,
-                                       boolean allowNull)
-                                throws ValidationException,
-                                       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. -

-

-
Specified by:
getValidNumber in interface Validator
-
-
-
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.
minValue - Lowest legal value for input.
maxValue - Highest legal value for input. -
Returns:
A validated number as a double. -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-getValidNumber

-
-public java.lang.Double getValidNumber(java.lang.String context,
-                                       java.lang.String input,
-                                       long minValue,
-                                       long maxValue,
-                                       boolean allowNull,
-                                       ValidationErrorList errors)
-                                throws IntrusionException
-
-
Description copied from interface: Validator
-
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. -

-

-
Specified by:
getValidNumber in interface Validator
-
-
-
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.
errors - If validation is in error, resulting error will be stored in the errorList by context -
Returns:
A validated number as a double. -
Throws: -
IntrusionException
-
-
-
- -

-isValidDouble

-
-public boolean isValidDouble(java.lang.String context,
-                             java.lang.String input,
-                             double minValue,
-                             double maxValue,
-                             boolean allowNull)
-                      throws IntrusionException
-
-
Description copied from interface: Validator
-
Returns true if input is a valid double within the range of minValue to maxValue. -

-

-
Specified by:
isValidDouble in interface Validator
-
-
-
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:
true, if input is a valid double. -
Throws: -
IntrusionException
-
-
-
- -

-getValidDouble

-
-public java.lang.Double getValidDouble(java.lang.String context,
-                                       java.lang.String input,
-                                       double minValue,
-                                       double maxValue,
-                                       boolean allowNull)
-                                throws ValidationException,
-                                       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. -

-

-
Specified by:
getValidDouble in interface Validator
-
-
-
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.
minValue - Lowest legal value for input.
maxValue - Highest legal value for input. -
Returns:
A validated real number as a double. -
Throws: -
IntrusionException -
ValidationException
-
-
-
- -

-getValidDouble

-
-public java.lang.Double getValidDouble(java.lang.String context,
-                                       java.lang.String input,
-                                       double minValue,
-                                       double maxValue,
-                                       boolean allowNull,
-                                       ValidationErrorList errors)
-                                throws IntrusionException
-
-
Description copied from interface: Validator
-
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. -

-

-
Specified by:
getValidDouble in interface Validator
-
-
-
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.
errors - If validation is in error, resulting error will be stored in the errorList by context -
Returns:
A validated real number as a double. -
Throws: -
IntrusionException
-
-
-
- -

-isValidInteger

-
-public boolean isValidInteger(java.lang.String context,
-                              java.lang.String input,
-                              int minValue,
-                              int maxValue,
-                              boolean allowNull)
-                       throws IntrusionException
-
-
Description copied from interface: Validator
-
Returns true if input is a valid integer within the range of minValue to maxValue. -

-

-
Specified by:
isValidInteger in interface Validator
-
-
-
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:
true, if input is a valid integer -
Throws: -
IntrusionException
-
-
-
- -

-getValidInteger

-
-public java.lang.Integer getValidInteger(java.lang.String context,
-                                         java.lang.String input,
-                                         int minValue,
-                                         int maxValue,
-                                         boolean allowNull)
-                                  throws ValidationException,
-                                         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. -

-

-
Specified by:
getValidInteger in interface Validator
-
-
-
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.
minValue - Lowest legal value for input.
maxValue - Highest legal value for input. -
Returns:
A validated number as an integer. -
Throws: -
IntrusionException -
ValidationException
-
-
-
- -

-getValidInteger

-
-public java.lang.Integer getValidInteger(java.lang.String context,
-                                         java.lang.String input,
-                                         int minValue,
-                                         int maxValue,
-                                         boolean allowNull,
-                                         ValidationErrorList errors)
-                                  throws IntrusionException
-
-
Description copied from interface: Validator
-
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. -

-

-
Specified by:
getValidInteger in interface Validator
-
-
-
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.
errors - If validation is in error, resulting error will be stored in the errorList by context -
Returns:
A validated number as an integer. -
Throws: -
IntrusionException
-
-
-
- -

-isValidFileContent

-
-public boolean isValidFileContent(java.lang.String context,
-                                  byte[] input,
-                                  int maxBytes,
-                                  boolean allowNull)
-                           throws IntrusionException
-
-
Returns true if input is valid file content. -

-

-
Specified by:
isValidFileContent in interface Validator
-
-
-
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:
true, if input contains valid file content. -
Throws: -
IntrusionException
-
-
-
- -

-getValidFileContent

-
-public byte[] getValidFileContent(java.lang.String context,
-                                  byte[] input,
-                                  int maxBytes,
-                                  boolean allowNull)
-                           throws ValidationException,
-                                  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. -

-

-
Specified by:
getValidFileContent in interface Validator
-
-
-
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:
A byte array containing valid file content. -
Throws: -
IntrusionException -
ValidationException
-
-
-
- -

-getValidFileContent

-
-public byte[] getValidFileContent(java.lang.String context,
-                                  byte[] input,
-                                  int maxBytes,
-                                  boolean allowNull,
-                                  ValidationErrorList errors)
-                           throws IntrusionException
-
-
Description copied from interface: Validator
-
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. -

-

-
Specified by:
getValidFileContent in interface Validator
-
-
-
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.
errors - If validation is in error, resulting error will be stored in the errorList by context. -
Returns:
A byte array containing valid file content. -
Throws: -
IntrusionException
-
-
-
- -

-isValidFileUpload

-
-public boolean isValidFileUpload(java.lang.String context,
-                                 java.lang.String directorypath,
-                                 java.lang.String filename,
-                                 byte[] content,
-                                 int maxBytes,
-                                 boolean allowNull)
-                          throws IntrusionException
-
-
Returns true if a file upload has a valid name, path, and content. -

-

-
Specified by:
isValidFileUpload in interface Validator
-
-
-
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.
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. -
Throws: -
IntrusionException
-
-
-
- -

-assertValidFileUpload

-
-public void assertValidFileUpload(java.lang.String context,
-                                  java.lang.String directorypath,
-                                  java.lang.String filename,
-                                  byte[] content,
-                                  int maxBytes,
-                                  boolean allowNull)
-                           throws ValidationException,
-                                  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. -

-

-
Specified by:
assertValidFileUpload in interface Validator
-
-
-
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.
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. -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-assertValidFileUpload

-
-public void assertValidFileUpload(java.lang.String context,
-                                  java.lang.String filepath,
-                                  java.lang.String filename,
-                                  byte[] content,
-                                  int maxBytes,
-                                  boolean allowNull,
-                                  ValidationErrorList errors)
-                           throws IntrusionException
-
-
ValidationErrorList variant of assertValidFileUpload -

-

-
Specified by:
assertValidFileUpload in interface Validator
-
-
-
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.
errors - If validation is in error, resulting error will be stored in the errorList by context -
Throws: -
IntrusionException
-
-
-
- -

-isValidHTTPRequest

-
-public boolean isValidHTTPRequest()
-                           throws 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 -

-

-
Specified by:
isValidHTTPRequest in interface Validator
-
-
- -
Returns:
true, if is a valid HTTP request -
Throws: -
IntrusionException
-
-
-
- -

-isValidHTTPRequest

-
-public boolean isValidHTTPRequest(javax.servlet.http.HttpServletRequest request)
-                           throws 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. -

-

-
-
-
- -
Throws: -
IntrusionException
-
-
-
- -

-assertIsValidHTTPRequest

-
-public void assertIsValidHTTPRequest()
-                              throws ValidationException,
-                                     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 -

-

-
Specified by:
assertIsValidHTTPRequest in interface Validator
-
-
- -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-isValidListItem

-
-public boolean isValidListItem(java.lang.String context,
-                               java.lang.String input,
-                               java.util.List list)
-
-
Description copied from interface: Validator
-
Returns true if input is a valid list item. -

-

-
Specified by:
isValidListItem in interface Validator
-
-
-
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:
true, if 'input' was found in 'list'.
-
-
-
- -

-getValidListItem

-
-public java.lang.String getValidListItem(java.lang.String context,
-                                         java.lang.String input,
-                                         java.util.List list)
-                                  throws ValidationException,
-                                         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. -

-

-
Specified by:
getValidListItem in interface Validator
-
-
-
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. -
Throws: -
IntrusionException -
ValidationException
-
-
-
- -

-getValidListItem

-
-public java.lang.String getValidListItem(java.lang.String context,
-                                         java.lang.String input,
-                                         java.util.List list,
-                                         ValidationErrorList errors)
-                                  throws IntrusionException
-
-
ValidationErrorList variant of getValidListItem -

-

-
Specified by:
getValidListItem in interface Validator
-
-
-
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'.
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. -
Throws: -
IntrusionException
-
-
-
- -

-isValidHTTPRequestParameterSet

-
-public boolean isValidHTTPRequestParameterSet(java.lang.String context,
-                                              java.util.Set requiredNames,
-                                              java.util.Set optionalNames)
-
-
Description copied from interface: Validator
-
Returns true if the parameters in the current request contain all required parameters and only optional ones in addition. -

-

-
Specified by:
isValidHTTPRequestParameterSet in interface Validator
-
-
-
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.
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.
-
-
-
- -

-assertIsValidHTTPRequestParameterSet

-
-public void assertIsValidHTTPRequestParameterSet(java.lang.String context,
-                                                 java.util.Set required,
-                                                 java.util.Set optional)
-                                          throws ValidationException,
-                                                 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. -

-

-
Specified by:
assertIsValidHTTPRequestParameterSet in interface Validator
-
-
-
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 -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-assertIsValidHTTPRequestParameterSet

-
-public void assertIsValidHTTPRequestParameterSet(java.lang.String context,
-                                                 java.util.Set required,
-                                                 java.util.Set optional,
-                                                 ValidationErrorList errors)
-                                          throws IntrusionException
-
-
ValidationErrorList variant of assertIsValidHTTPRequestParameterSet -

-

-
Specified by:
assertIsValidHTTPRequestParameterSet in interface Validator
-
-
-
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
errors - If validation is in error, resulting error will be stored in the errorList by context -
Throws: -
IntrusionException
-
-
-
- -

-isValidPrintable

-
-public boolean isValidPrintable(java.lang.String context,
-                                byte[] input,
-                                int maxLength,
-                                boolean allowNull)
-                         throws IntrusionException
-
-
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) -

-

-
Specified by:
isValidPrintable in interface Validator
-
-
-
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 -
Throws: -
IntrusionException
See Also:
org.owasp.esapi.Validator#isValidASCIIFileContent(byte[])
-
-
-
- -

-getValidPrintable

-
-public byte[] getValidPrintable(java.lang.String context,
-                                byte[] input,
-                                int maxLength,
-                                boolean allowNull)
-                         throws ValidationException,
-                                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. -

-

-
Specified by:
getValidPrintable in interface Validator
-
-
-
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' -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-getValidPrintable

-
-public byte[] getValidPrintable(java.lang.String context,
-                                byte[] input,
-                                int maxLength,
-                                boolean allowNull,
-                                ValidationErrorList errors)
-                         throws IntrusionException
-
-
ValidationErrorList variant of getValidPrintable -

-

-
Specified by:
getValidPrintable in interface Validator
-
-
-
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.
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' -
Throws: -
IntrusionException
-
-
-
- -

-isValidPrintable

-
-public boolean isValidPrintable(java.lang.String context,
-                                java.lang.String input,
-                                int maxLength,
-                                boolean allowNull)
-                         throws IntrusionException
-
-
Description copied from interface: Validator
-
Returns true if input contains only valid printable ASCII characters (32-126). -

-

-
Specified by:
isValidPrintable in interface Validator
-
-
-
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 -
Throws: -
IntrusionException
-
-
-
- -

-getValidPrintable

-
-public java.lang.String getValidPrintable(java.lang.String context,
-                                          java.lang.String input,
-                                          int maxLength,
-                                          boolean allowNull)
-                                   throws ValidationException,
-                                          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. -

-

-
Specified by:
getValidPrintable in interface Validator
-
-
-
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' -
Throws: -
ValidationException -
IntrusionException
-
-
-
- -

-getValidPrintable

-
-public java.lang.String getValidPrintable(java.lang.String context,
-                                          java.lang.String input,
-                                          int maxLength,
-                                          boolean allowNull,
-                                          ValidationErrorList errors)
-                                   throws IntrusionException
-
-
ValidationErrorList variant of getValidPrintable -

-

-
Specified by:
getValidPrintable in interface Validator
-
-
-
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.
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' -
Throws: -
IntrusionException
-
-
-
- -

-isValidRedirectLocation

-
-public boolean isValidRedirectLocation(java.lang.String context,
-                                       java.lang.String input,
-                                       boolean allowNull)
-                                throws IntrusionException
-
-
Returns true if input is a valid redirect location. -

-

-
Specified by:
isValidRedirectLocation in interface Validator
-
-
-
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. -
Throws: -
IntrusionException
-
-
-
- -

-getValidRedirectLocation

-
-public java.lang.String getValidRedirectLocation(java.lang.String context,
-                                                 java.lang.String input,
-                                                 boolean allowNull)
-                                          throws ValidationException,
-                                                 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. -

-

-
Specified by:
getValidRedirectLocation in interface Validator
-
-
-
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" -
Throws: -
IntrusionException -
ValidationException
-
-
-
- -

-getValidRedirectLocation

-
-public java.lang.String getValidRedirectLocation(java.lang.String context,
-                                                 java.lang.String input,
-                                                 boolean allowNull,
-                                                 ValidationErrorList errors)
-                                          throws IntrusionException
-
-
ValidationErrorList variant of getValidRedirectLocation -

-

-
Specified by:
getValidRedirectLocation in interface Validator
-
-
-
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.
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" -
Throws: -
IntrusionException
-
-
-
- -

-safeReadLine

-
-public java.lang.String safeReadLine(java.io.InputStream in,
-                                     int max)
-                              throws ValidationException
-
-
This implementation reads until a newline or the specified number of - characters. -

-

-
Specified by:
safeReadLine in interface Validator
-
-
-
Parameters:
in - the in
max - the max -
Returns:
the string -
Throws: -
ValidationException - the validation exception
See Also:
Validator.safeReadLine(java.io.InputStream, - int)
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/EncoderTest.html b/javadoc/org/owasp/esapi/reference/EncoderTest.html deleted file mode 100644 index 479145361..000000000 --- a/javadoc/org/owasp/esapi/reference/EncoderTest.html +++ /dev/null @@ -1,656 +0,0 @@ - - - - - - -EncoderTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class EncoderTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.reference.EncoderTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class EncoderTest
extends junit.framework.TestCase
- -

-The Class EncoderTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
EncoderTest(java.lang.String testName) - -
-          Instantiates a new encoder test.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestCanonicalize() - -
-          Test of canonicalize method, of class org.owasp.esapi.Encoder.
- voidtestDecodeFromBase64() - -
-          Test of decodeFromBase64 method, of class org.owasp.esapi.Encoder.
- voidtestDecodeFromURL() - -
-          Test of decodeFromURL method, of class org.owasp.esapi.Encoder.
- voidtestEncodeForBase64() - -
-          Test of encodeForBase64 method, of class org.owasp.esapi.Encoder.
- voidtestEncodeForCSS() - -
-           
- voidtestEncodeForDN() - -
-          Test of encodeForLDAP method, of class org.owasp.esapi.Encoder.
- voidtestEncodeForHTML() - -
-          Test of encodeForHTML method, of class org.owasp.esapi.Encoder.
- voidtestEncodeForHTMLAttribute() - -
-          Test of encodeForHTMLAttribute method, of class org.owasp.esapi.Encoder.
- voidtestEncodeForJavascript() - -
-          Test of encodeForJavaScript method, of class org.owasp.esapi.Encoder.
- voidtestEncodeForLDAP() - -
-          Test of encodeForLDAP method, of class org.owasp.esapi.Encoder.
- voidtestEncodeForSQL() - -
-          Test of encodeForSQL method, of class org.owasp.esapi.Encoder.
- voidtestEncodeForURL() - -
-          Test of encodeForURL method, of class org.owasp.esapi.Encoder.
- voidtestEncodeForVBScript() - -
-           
- voidtestEncodeForXML() - -
-          Test of encodeForXML method, of class org.owasp.esapi.Encoder.
- voidtestEncodeForXMLAttribute() - -
-          Test of encodeForXMLAttribute method, of class org.owasp.esapi.Encoder.
- voidtestEncodeForXPath() - -
-          Test of encodeForXPath method, of class org.owasp.esapi.Encoder.
- voidtestNormalize() - -
-          Test of normalize method, of class org.owasp.esapi.Validator.
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-EncoderTest

-
-public EncoderTest(java.lang.String testName)
-
-
Instantiates a new encoder test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testCanonicalize

-
-public void testCanonicalize()
-                      throws EncodingException
-
-
Test of canonicalize method, of class org.owasp.esapi.Encoder. -

-

- -
Throws: -
EncodingException
-
-
-
- -

-testNormalize

-
-public void testNormalize()
-                   throws ValidationException
-
-
Test of normalize method, of class org.owasp.esapi.Validator. -

-

- -
Throws: -
ValidationException - the validation exception
-
-
-
- -

-testEncodeForHTML

-
-public void testEncodeForHTML()
-                       throws java.lang.Exception
-
-
Test of encodeForHTML method, of class org.owasp.esapi.Encoder. -

-

- -
Throws: -
java.lang.Exception
-
-
-
- -

-testEncodeForHTMLAttribute

-
-public void testEncodeForHTMLAttribute()
-
-
Test of encodeForHTMLAttribute method, of class org.owasp.esapi.Encoder. -

-

-
-
-
-
- -

-testEncodeForCSS

-
-public void testEncodeForCSS()
-
-
-
-
-
-
- -

-testEncodeForJavascript

-
-public void testEncodeForJavascript()
-
-
Test of encodeForJavaScript method, of class org.owasp.esapi.Encoder. -

-

-
-
-
-
- -

-testEncodeForVBScript

-
-public void testEncodeForVBScript()
-
-
-
-
-
-
- -

-testEncodeForXPath

-
-public void testEncodeForXPath()
-
-
Test of encodeForXPath method, of class org.owasp.esapi.Encoder. -

-

-
-
-
-
- -

-testEncodeForSQL

-
-public void testEncodeForSQL()
-
-
Test of encodeForSQL method, of class org.owasp.esapi.Encoder. -

-

-
-
-
-
- -

-testEncodeForLDAP

-
-public void testEncodeForLDAP()
-
-
Test of encodeForLDAP method, of class org.owasp.esapi.Encoder. -

-

-
-
-
-
- -

-testEncodeForDN

-
-public void testEncodeForDN()
-
-
Test of encodeForLDAP method, of class org.owasp.esapi.Encoder. -

-

-
-
-
-
- -

-testEncodeForXML

-
-public void testEncodeForXML()
-
-
Test of encodeForXML method, of class org.owasp.esapi.Encoder. -

-

-
-
-
-
- -

-testEncodeForXMLAttribute

-
-public void testEncodeForXMLAttribute()
-
-
Test of encodeForXMLAttribute method, of class org.owasp.esapi.Encoder. -

-

-
-
-
-
- -

-testEncodeForURL

-
-public void testEncodeForURL()
-                      throws java.lang.Exception
-
-
Test of encodeForURL method, of class org.owasp.esapi.Encoder. -

-

- -
Throws: -
java.lang.Exception
-
-
-
- -

-testDecodeFromURL

-
-public void testDecodeFromURL()
-                       throws java.lang.Exception
-
-
Test of decodeFromURL method, of class org.owasp.esapi.Encoder. -

-

- -
Throws: -
java.lang.Exception
-
-
-
- -

-testEncodeForBase64

-
-public void testEncodeForBase64()
-
-
Test of encodeForBase64 method, of class org.owasp.esapi.Encoder. -

-

-
-
-
-
- -

-testDecodeFromBase64

-
-public void testDecodeFromBase64()
-
-
Test of decodeFromBase64 method, of class org.owasp.esapi.Encoder. -

-

-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/EncryptedPropertiesTest.html b/javadoc/org/owasp/esapi/reference/EncryptedPropertiesTest.html deleted file mode 100644 index 7756608f9..000000000 --- a/javadoc/org/owasp/esapi/reference/EncryptedPropertiesTest.html +++ /dev/null @@ -1,432 +0,0 @@ - - - - - - -EncryptedPropertiesTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class EncryptedPropertiesTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.reference.EncryptedPropertiesTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class EncryptedPropertiesTest
extends junit.framework.TestCase
- -

-The Class EncryptedPropertiesTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
EncryptedPropertiesTest(java.lang.String testName) - -
-          Instantiates a new encrypted properties test.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestGetProperty() - -
-          Test of getProperty method, of class org.owasp.esapi.EncryptedProperties.
- voidtestKeySet() - -
-          Test of keySet method, of class org.owasp.esapi.EncryptedProperties.
- voidtestLoad() - -
-          Test of load method, of class org.owasp.esapi.EncryptedProperties.
- voidtestMain() - -
-          Test of store method, of class org.owasp.esapi.EncryptedProperties.
- voidtestSetProperty() - -
-          Test of setProperty method, of class org.owasp.esapi.EncryptedProperties.
- voidtestStore() - -
-          Test of store method, of class org.owasp.esapi.EncryptedProperties.
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-EncryptedPropertiesTest

-
-public EncryptedPropertiesTest(java.lang.String testName)
-
-
Instantiates a new encrypted properties test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testGetProperty

-
-public void testGetProperty()
-                     throws EncryptionException
-
-
Test of getProperty method, of class org.owasp.esapi.EncryptedProperties. -

-

- -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-testSetProperty

-
-public void testSetProperty()
-                     throws EncryptionException
-
-
Test of setProperty method, of class org.owasp.esapi.EncryptedProperties. -

-

- -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-testKeySet

-
-public void testKeySet()
-                throws java.lang.Exception
-
-
Test of keySet method, of class org.owasp.esapi.EncryptedProperties. -

-

- -
Throws: -
java.lang.Exception
-
-
-
- -

-testLoad

-
-public void testLoad()
-              throws java.lang.Exception
-
-
Test of load method, of class org.owasp.esapi.EncryptedProperties. -

-

- -
Throws: -
java.lang.Exception
-
-
-
- -

-testStore

-
-public void testStore()
-               throws java.lang.Exception
-
-
Test of store method, of class org.owasp.esapi.EncryptedProperties. -

-

- -
Throws: -
java.lang.Exception
-
-
-
- -

-testMain

-
-public void testMain()
-              throws java.lang.Exception
-
-
Test of store method, of class org.owasp.esapi.EncryptedProperties. -

-

- -
Throws: -
java.lang.Exception
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/EncryptorTest.html b/javadoc/org/owasp/esapi/reference/EncryptorTest.html deleted file mode 100644 index 066141f6a..000000000 --- a/javadoc/org/owasp/esapi/reference/EncryptorTest.html +++ /dev/null @@ -1,455 +0,0 @@ - - - - - - -EncryptorTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class EncryptorTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.reference.EncryptorTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class EncryptorTest
extends junit.framework.TestCase
- -

-The Class EncryptorTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
EncryptorTest(java.lang.String testName) - -
-          Instantiates a new encryptor test.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestDecrypt() - -
-          Test of decrypt method, of class org.owasp.esapi.Encryptor.
- voidtestEncrypt() - -
-          Test of encrypt method, of class org.owasp.esapi.Encryptor.
- voidtestHash() - -
-          Test of hash method, of class org.owasp.esapi.Encryptor.
- voidtestSeal() - -
-          Test of seal method, of class org.owasp.esapi.Encryptor.
- voidtestSign() - -
-          Test of sign method, of class org.owasp.esapi.Encryptor.
- voidtestVerifySeal() - -
-          Test of verifySeal method, of class org.owasp.esapi.Encryptor.
- voidtestVerifySignature() - -
-          Test of verifySignature method, of class org.owasp.esapi.Encryptor.
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-EncryptorTest

-
-public EncryptorTest(java.lang.String testName)
-
-
Instantiates a new encryptor test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testHash

-
-public void testHash()
-              throws EncryptionException
-
-
Test of hash method, of class org.owasp.esapi.Encryptor. -

-

- -
Throws: -
EncryptionException
-
-
-
- -

-testEncrypt

-
-public void testEncrypt()
-                 throws EncryptionException
-
-
Test of encrypt method, of class org.owasp.esapi.Encryptor. -

-

- -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-testDecrypt

-
-public void testDecrypt()
-
-
Test of decrypt method, of class org.owasp.esapi.Encryptor. -

-

-
-
-
-
- -

-testSign

-
-public void testSign()
-              throws EncryptionException
-
-
Test of sign method, of class org.owasp.esapi.Encryptor. -

-

- -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-testVerifySignature

-
-public void testVerifySignature()
-                         throws EncryptionException
-
-
Test of verifySignature method, of class org.owasp.esapi.Encryptor. -

-

- -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-testSeal

-
-public void testSeal()
-              throws IntegrityException
-
-
Test of seal method, of class org.owasp.esapi.Encryptor. -

-

- -
Throws: -
EncryptionException - the encryption exception -
IntegrityException
-
-
-
- -

-testVerifySeal

-
-public void testVerifySeal()
-                    throws EnterpriseSecurityException
-
-
Test of verifySeal method, of class org.owasp.esapi.Encryptor. -

-

- -
Throws: -
EncryptionException - the encryption exception -
EnterpriseSecurityException
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/ExecutorTest.html b/javadoc/org/owasp/esapi/reference/ExecutorTest.html deleted file mode 100644 index e23bf2561..000000000 --- a/javadoc/org/owasp/esapi/reference/ExecutorTest.html +++ /dev/null @@ -1,312 +0,0 @@ - - - - - - -ExecutorTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class ExecutorTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.reference.ExecutorTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class ExecutorTest
extends junit.framework.TestCase
- -

-The Class ExecutorTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
ExecutorTest(java.lang.String testName) - -
-          Instantiates a new executor test.
-  - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestExecuteSystemCommand() - -
-          Test of executeOSCommand method, of class org.owasp.esapi.Executor
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-ExecutorTest

-
-public ExecutorTest(java.lang.String testName)
-
-
Instantiates a new executor test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testExecuteSystemCommand

-
-public void testExecuteSystemCommand()
-                              throws java.lang.Exception
-
-
Test of executeOSCommand method, of class org.owasp.esapi.Executor -

-

- -
Throws: -
java.lang.Exception - the exception
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/FileBasedAccessController.html b/javadoc/org/owasp/esapi/reference/FileBasedAccessController.html deleted file mode 100644 index 2fcd57263..000000000 --- a/javadoc/org/owasp/esapi/reference/FileBasedAccessController.html +++ /dev/null @@ -1,588 +0,0 @@ - - - - - - -FileBasedAccessController - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class FileBasedAccessController

-
-java.lang.Object
-  extended byorg.owasp.esapi.reference.FileBasedAccessController
-
-
-
All Implemented Interfaces:
AccessController
-
-
-
-
public class FileBasedAccessController
extends java.lang.Object
implements AccessController
- -

-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 /
  • -
-

- -

-

-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
AccessController
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
FileBasedAccessController() - -
-           
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- voidassertAuthorizedForData(java.lang.String key) - -
-          Checks if an account is authorized to access the referenced data.
- voidassertAuthorizedForFile(java.lang.String filepath) - -
-          Checks if an account is authorized to access the referenced file.
- voidassertAuthorizedForFunction(java.lang.String functionName) - -
-          Checks if an account is authorized to access the referenced function.
- voidassertAuthorizedForService(java.lang.String serviceName) - -
-          Checks if an account is authorized to access the referenced service.
- voidassertAuthorizedForURL(java.lang.String url) - -
-          Checks if an account is authorized to access the referenced URL.
- booleanisAuthorizedForData(java.lang.String key) - -
-          Checks if an account is authorized to access the referenced data.
- booleanisAuthorizedForFile(java.lang.String filepath) - -
-          Checks if an account is authorized to access the referenced file.
- booleanisAuthorizedForFunction(java.lang.String functionName) - -
-          Checks if an account is authorized to access the referenced function.
- booleanisAuthorizedForService(java.lang.String serviceName) - -
-          Checks if an account is authorized to access the referenced service.
- booleanisAuthorizedForURL(java.lang.String url) - -
-          Checks if an account is authorized to access the referenced URL.
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-FileBasedAccessController

-
-public FileBasedAccessController()
-
-
- - - - - - - - -
-Method Detail
- -

-isAuthorizedForURL

-
-public boolean isAuthorizedForURL(java.lang.String url)
-
-
Description copied from interface: AccessController
-
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: -
ESAPI.accessController().isAuthorizedForURL(request.getRequestURI().toString());
-

-

-
Specified by:
isAuthorizedForURL in interface AccessController
-
-
- -
Returns:
true, if is authorized for URL
-
-
-
- -

-isAuthorizedForFunction

-
-public boolean isAuthorizedForFunction(java.lang.String functionName)
-
-
Description copied from interface: AccessController
-
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. -

-

-
Specified by:
isAuthorizedForFunction in interface AccessController
-
-
-
Parameters:
functionName - the function name -
Returns:
true, if is authorized for function
-
-
-
- -

-isAuthorizedForData

-
-public boolean isAuthorizedForData(java.lang.String key)
-
-
Description copied from interface: AccessController
-
Checks if an account is authorized to access the referenced data. The implementation should define the data - "namespace" to be enforced. -

-

-
Specified by:
isAuthorizedForData in interface AccessController
-
-
-
Parameters:
key - the key -
Returns:
true, if is authorized for data
-
-
-
- -

-isAuthorizedForFile

-
-public boolean isAuthorizedForFile(java.lang.String filepath)
-
-
Description copied from interface: AccessController
-
Checks if an account is authorized to access the referenced file. The implementation should be extremely careful - about canonicalization. -

-

-
Specified by:
isAuthorizedForFile in interface AccessController
-
-
-
Parameters:
filepath - the path of the file to be checked, including filename -
Returns:
true, if is authorized for file
See Also:
Encoder.canonicalize(String)
-
-
-
- -

-isAuthorizedForService

-
-public boolean isAuthorizedForService(java.lang.String serviceName)
-
-
Description copied from interface: AccessController
-
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. -

-

-
Specified by:
isAuthorizedForService in interface AccessController
-
-
-
Parameters:
serviceName - the service name -
Returns:
true, if is authorized for service
-
-
-
- -

-assertAuthorizedForURL

-
-public void assertAuthorizedForURL(java.lang.String url)
-                            throws AccessControlException
-
-
Description copied from interface: AccessController
-
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: -
ESAPI.accessController().assertAuthorizedForURL(request.getRequestURI().toString());
-

-

-
Specified by:
assertAuthorizedForURL in interface AccessController
-
-
-
Parameters:
url - the url as returned by request.getRequestURI().toString() -
Throws: -
AccessControlException - if access is not permitted
-
-
-
- -

-assertAuthorizedForFunction

-
-public void assertAuthorizedForFunction(java.lang.String functionName)
-                                 throws AccessControlException
-
-
Description copied from interface: AccessController
-
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. -

-

-
Specified by:
assertAuthorizedForFunction in interface AccessController
-
-
-
Parameters:
functionName - the function name -
Throws: -
AccessControlException - if access is not permitted
-
-
-
- -

-assertAuthorizedForData

-
-public void assertAuthorizedForData(java.lang.String key)
-                             throws AccessControlException
-
-
Description copied from interface: AccessController
-
Checks if an account is authorized to access the referenced data. The implementation should define the data - "namespace" to be enforced. -

-

-
Specified by:
assertAuthorizedForData in interface AccessController
-
-
-
Parameters:
key - the key -
Throws: -
AccessControlException - is access is not permitted
-
-
-
- -

-assertAuthorizedForFile

-
-public void assertAuthorizedForFile(java.lang.String filepath)
-                             throws AccessControlException
-
-
Description copied from interface: AccessController
-
Checks if an account is authorized to access the referenced file. The implementation should be extremely careful - about canonicalization. -

-

-
Specified by:
assertAuthorizedForFile in interface AccessController
-
-
-
Parameters:
filepath - the path of the file to be checked, including filename -
Throws: -
AccessControlException - is access is not permitted
See Also:
Encoder.canonicalize(String)
-
-
-
- -

-assertAuthorizedForService

-
-public void assertAuthorizedForService(java.lang.String serviceName)
-                                throws AccessControlException
-
-
Description copied from interface: AccessController
-
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. -

-

-
Specified by:
assertAuthorizedForService in interface AccessController
-
-
-
Parameters:
serviceName - the service name -
Throws: -
AccessControlException
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/FileBasedAuthenticator.html b/javadoc/org/owasp/esapi/reference/FileBasedAuthenticator.html deleted file mode 100644 index 8c749791c..000000000 --- a/javadoc/org/owasp/esapi/reference/FileBasedAuthenticator.html +++ /dev/null @@ -1,827 +0,0 @@ - - - - - - -FileBasedAuthenticator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class FileBasedAuthenticator

-
-java.lang.Object
-  extended byorg.owasp.esapi.reference.FileBasedAuthenticator
-
-
-
All Implemented Interfaces:
Authenticator
-
-
-
-
public class FileBasedAuthenticator
extends java.lang.Object
implements Authenticator
- -

-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
- 
- 
-

- -

-

-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams at Aspect Security
-
See Also:
Authenticator
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
FileBasedAuthenticator() - -
-           
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- voidchangePassword(User user, - java.lang.String currentPassword, - java.lang.String newPassword, - java.lang.String newPassword2) - -
-          Changes the password for the specified user.
- voidclearCurrent() - -
-          Clears all threadlocal variables from the thread.
- UsercreateUser(java.lang.String accountName, - java.lang.String password1, - java.lang.String password2) - -
-          Creates a new User with the information provided.
- booleanexists(java.lang.String accountName) - -
-          Determine if the account exists.
- java.lang.StringgenerateStrongPassword() - -
-          Generate a strong password.
- java.lang.StringgenerateStrongPassword(User user, - java.lang.String oldPassword) - -
-          Generate strong password that takes into account the user's information and old password.
- UsergetCurrentUser() - -
-          Returns the currently logged in User.
- UsergetUser(long accountId) - -
-          Gets the user object with the matching account name or null if there is no match.
- UsergetUser(java.lang.String accountName) - -
-          Gets the user object with the matching account name or null if there is no match.
- java.util.SetgetUserNames() - -
-          Gets the user names.
- java.lang.StringhashPassword(java.lang.String password, - java.lang.String accountName) - -
-          Returns a string representation of the hashed password, using the - accountName as the salt.
- Userlogin(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.
- voidlogout() - -
-          Log out the current user.
-static voidmain(java.lang.String[] args) - -
-          Fail safe main program to add or update an account in an emergency.
- voidremoveUser(java.lang.String accountName) - -
-          Removes the account.
- voidsetCurrentUser(User user) - -
-          Sets the currently logged in User.
- voidverifyAccountNameStrength(java.lang.String newAccountName) - -
-          Ensures that the account name passes site-specific complexity requirements, like minimum length.
- booleanverifyPassword(User user, - java.lang.String password) - -
-          Verify that the supplied password matches the password for this user.
- voidverifyPasswordStrength(java.lang.String oldPassword, - java.lang.String newPassword) - -
-          Ensures that the password meets site-specific complexity requirements.
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-FileBasedAuthenticator

-
-public FileBasedAuthenticator()
-
-
- - - - - - - - -
-Method Detail
- -

-main

-
-public static void main(java.lang.String[] args)
-                 throws java.lang.Exception
-
-
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: -

- 
- java -Dorg.owasp.esapi.resources="/path/resources" -classpath esapi.jar org.owasp.esapi.Authenticator alice password admin
- 
- 
-

-

-
-
-
-
Parameters:
args - the args -
Throws: -
AuthenticationException - the authentication exception -
java.lang.Exception
-
-
-
- -

-clearCurrent

-
-public void clearCurrent()
-
-
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. -

-

-
Specified by:
clearCurrent in interface Authenticator
-
-
-
-
-
-
- -

-createUser

-
-public User createUser(java.lang.String accountName,
-                       java.lang.String password1,
-                       java.lang.String password2)
-                throws AuthenticationException
-
-
Description copied from interface: Authenticator
-
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. -

-

-
Specified by:
createUser in interface Authenticator
-
-
-
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. -
Returns:
the User that has been created -
Throws: -
AuthenticationException - if user creation fails
-
-
-
- -

-exists

-
-public boolean exists(java.lang.String accountName)
-
-
Description copied from interface: Authenticator
-
Determine if the account exists. -

-

-
Specified by:
exists in interface Authenticator
-
-
-
Parameters:
accountName - the account name -
Returns:
true, if the account exists
-
-
-
- -

-generateStrongPassword

-
-public java.lang.String generateStrongPassword()
-
-
Description copied from interface: Authenticator
-
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. -

-

-
Specified by:
generateStrongPassword in interface Authenticator
-
-
- -
Returns:
a password with strong password strength
-
-
-
- -

-changePassword

-
-public void changePassword(User user,
-                           java.lang.String currentPassword,
-                           java.lang.String newPassword,
-                           java.lang.String newPassword2)
-                    throws AuthenticationException
-
-
Description copied from interface: Authenticator
-
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. -

-

-
Specified by:
changePassword in interface Authenticator
-
-
-
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 -
Throws: -
AuthenticationException - if any errors occur
-
-
-
- -

-verifyPassword

-
-public boolean verifyPassword(User user,
-                              java.lang.String password)
-
-
Description copied from interface: Authenticator
-
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. -

-

-
Specified by:
verifyPassword in interface Authenticator
-
-
-
Parameters:
user - the user
password - the password -
Returns:
true, if the password is correct for the specified user
-
-
-
- -

-generateStrongPassword

-
-public java.lang.String generateStrongPassword(User user,
-                                               java.lang.String oldPassword)
-
-
Description copied from interface: Authenticator
-
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. -

-

-
Specified by:
generateStrongPassword in interface Authenticator
-
-
-
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. -
Returns:
a password with strong password strength
-
-
-
- -

-getCurrentUser

-
-public User getCurrentUser()
-
-
Description copied from interface: Authenticator
-
Returns the currently logged in User. -

-

-
Specified by:
getCurrentUser in interface Authenticator
-
-
- -
Returns:
the matching User object, or the Anonymous user if no match - exists
-
-
-
- -

-getUser

-
-public User getUser(long accountId)
-
-
Gets the user object with the matching account name or null if there is no match. -

-

-
Specified by:
getUser in interface Authenticator
-
-
-
Parameters:
accountId - the account id -
Returns:
the user, or null if not matched.
-
-
-
- -

-getUser

-
-public User getUser(java.lang.String accountName)
-
-
Gets the user object with the matching account name or null if there is no match. -

-

-
Specified by:
getUser in interface Authenticator
-
-
-
Parameters:
accountName - the account name -
Returns:
the user, or null if not matched.
-
-
-
- -

-getUserNames

-
-public java.util.Set getUserNames()
-
-
Gets the user names. -

-

-
Specified by:
getUserNames in interface Authenticator
-
-
- -
Returns:
list of user account names
-
-
-
- -

-hashPassword

-
-public java.lang.String hashPassword(java.lang.String password,
-                                     java.lang.String accountName)
-                              throws EncryptionException
-
-
Description copied from interface: Authenticator
-
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. -

-

-
Specified by:
hashPassword in interface Authenticator
-
-
-
Parameters:
password - the password to hash
accountName - the account name to use as the salt -
Returns:
the hashed password -
Throws: -
EncryptionException
-
-
-
- -

-removeUser

-
-public void removeUser(java.lang.String accountName)
-                throws AuthenticationException
-
-
Description copied from interface: Authenticator
-
Removes the account. -

-

-
Specified by:
removeUser in interface Authenticator
-
-
-
Parameters:
accountName - the account name to remove -
Throws: -
AuthenticationException - the authentication exception if user does not exist
-
-
-
- -

-login

-
-public User login(javax.servlet.http.HttpServletRequest request,
-                  javax.servlet.http.HttpServletResponse response)
-           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. 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. -

-

-
Specified by:
login in interface Authenticator
-
-
-
Parameters:
request - the request
response - the response -
Returns:
the user -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-logout

-
-public void logout()
-
-
Log out the current user. -

-

-
Specified by:
logout in interface Authenticator
-
-
-
-
-
-
- -

-setCurrentUser

-
-public void setCurrentUser(User user)
-
-
Description copied from interface: Authenticator
-
Sets the currently logged in User. -

-

-
Specified by:
setCurrentUser in interface Authenticator
-
-
-
Parameters:
user - the user to set as the current user
-
-
-
- -

-verifyAccountNameStrength

-
-public void verifyAccountNameStrength(java.lang.String newAccountName)
-                               throws AuthenticationException
-
-
Description copied from interface: Authenticator
-
Ensures that the account name passes site-specific complexity requirements, like minimum length. -

-

-
Specified by:
verifyAccountNameStrength in interface Authenticator
-
-
-
Parameters:
newAccountName - the account name -
Throws: -
AuthenticationException - if account name does not meet complexity requirements
-
-
-
- -

-verifyPasswordStrength

-
-public void verifyPasswordStrength(java.lang.String oldPassword,
-                                   java.lang.String newPassword)
-                            throws AuthenticationException
-
-
Description copied from interface: Authenticator
-
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. -

-

-
Specified by:
verifyPasswordStrength in interface Authenticator
-
-
-
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
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/HTTPUtilitiesTest.html b/javadoc/org/owasp/esapi/reference/HTTPUtilitiesTest.html deleted file mode 100644 index 981ff9b86..000000000 --- a/javadoc/org/owasp/esapi/reference/HTTPUtilitiesTest.html +++ /dev/null @@ -1,554 +0,0 @@ - - - - - - -HTTPUtilitiesTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class HTTPUtilitiesTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.reference.HTTPUtilitiesTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class HTTPUtilitiesTest
extends junit.framework.TestCase
- -

-The Class HTTPUtilitiesTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
HTTPUtilitiesTest(java.lang.String testName) - -
-          Instantiates a new HTTP utilities test.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestAddCSRFToken() - -
-          Test of addCSRFToken method, of class org.owasp.esapi.HTTPUtilities.
- voidtestChangeSessionIdentifier() - -
-          Test of sendRedirect method, of class org.owasp.esapi.HTTPUtilities.
- voidtestGetFileUploads() - -
-          Test of formatHttpRequestForLog method, of class org.owasp.esapi.HTTPUtilities.
- voidtestGetStateFromEncryptedCookie() - -
-           
- voidtestIsValidHTTPRequest() - -
-          Test of isValidHTTPRequest method, of class org.owasp.esapi.HTTPUtilities.
- voidtestKillAllCookies() - -
-          Test of killAllCookies method, of class org.owasp.esapi.HTTPUtilities.
- voidtestKillCookie() - -
-          Test of killCookie method, of class org.owasp.esapi.HTTPUtilities.
- voidtestSaveStateInEncryptedCookie() - -
-           
- voidtestSendSafeRedirect() - -
-          Test of sendRedirect method, of class org.owasp.esapi.HTTPUtilities.
- voidtestSetCookie() - -
-          Test of setCookie method, of class org.owasp.esapi.HTTPUtilities.
- voidtestSetNoCacheHeaders() - -
-          Test set no cache headers.
- voidtestSetRememberToken() - -
-           
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-HTTPUtilitiesTest

-
-public HTTPUtilitiesTest(java.lang.String testName)
-
-
Instantiates a new HTTP utilities test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testAddCSRFToken

-
-public void testAddCSRFToken()
-                      throws AuthenticationException
-
-
Test of addCSRFToken method, of class org.owasp.esapi.HTTPUtilities. -

-

- -
Throws: -
AuthenticationException
-
-
-
- -

-testChangeSessionIdentifier

-
-public void testChangeSessionIdentifier()
-                                 throws EnterpriseSecurityException
-
-
Test of sendRedirect method, of class org.owasp.esapi.HTTPUtilities. -

-

- -
Throws: -
ValidationException - the validation exception -
java.io.IOException - Signals that an I/O exception has occurred. -
AuthenticationException - the authentication exception -
EnterpriseSecurityException
-
-
-
- -

-testGetFileUploads

-
-public void testGetFileUploads()
-                        throws java.io.IOException
-
-
Test of formatHttpRequestForLog method, of class org.owasp.esapi.HTTPUtilities. -

-

- -
Throws: -
java.io.IOException
-
-
-
- -

-testIsValidHTTPRequest

-
-public void testIsValidHTTPRequest()
-
-
Test of isValidHTTPRequest method, of class org.owasp.esapi.HTTPUtilities. -

-

-
-
-
-
- -

-testKillAllCookies

-
-public void testKillAllCookies()
-
-
Test of killAllCookies method, of class org.owasp.esapi.HTTPUtilities. -

-

-
-
-
-
- -

-testKillCookie

-
-public void testKillCookie()
-
-
Test of killCookie method, of class org.owasp.esapi.HTTPUtilities. -

-

-
-
-
-
- -

-testSendSafeRedirect

-
-public void testSendSafeRedirect()
-                          throws ValidationException,
-                                 java.io.IOException
-
-
Test of sendRedirect method, of class org.owasp.esapi.HTTPUtilities. -

-

- -
Throws: -
ValidationException - the validation exception -
java.io.IOException - Signals that an I/O exception has occurred.
-
-
-
- -

-testSetCookie

-
-public void testSetCookie()
-
-
Test of setCookie method, of class org.owasp.esapi.HTTPUtilities. -

-

-
-
-
-
- -

-testGetStateFromEncryptedCookie

-
-public void testGetStateFromEncryptedCookie()
-
-
-
-
-
-
- -

-testSaveStateInEncryptedCookie

-
-public void testSaveStateInEncryptedCookie()
-
-
-
-
-
-
- -

-testSetNoCacheHeaders

-
-public void testSetNoCacheHeaders()
-
-
Test set no cache headers. -

-

-
-
-
-
- -

-testSetRememberToken

-
-public void testSetRememberToken()
-                          throws AuthenticationException
-
-
- -
Throws: -
AuthenticationException
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/IntegerAccessReferenceMap.html b/javadoc/org/owasp/esapi/reference/IntegerAccessReferenceMap.html deleted file mode 100644 index cdf09a9c1..000000000 --- a/javadoc/org/owasp/esapi/reference/IntegerAccessReferenceMap.html +++ /dev/null @@ -1,439 +0,0 @@ - - - - - - -IntegerAccessReferenceMap - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class IntegerAccessReferenceMap

-
-java.lang.Object
-  extended byorg.owasp.esapi.reference.IntegerAccessReferenceMap
-
-
-
All Implemented Interfaces:
AccessReferenceMap
-
-
-
-
public class IntegerAccessReferenceMap
extends java.lang.Object
implements AccessReferenceMap
- -

-Reference implementation of the AccessReferenceMap interface. This - implementation generates integers for indirect references. -

- -

-

-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
AccessReferenceMap
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
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.StringaddDirectReference(java.lang.Object direct) - -
-          Adds a direct reference and a new indirect reference, overwriting any existing values.
- java.lang.ObjectgetDirectReference(java.lang.String indirectReference) - -
-          Get the original direct object reference from an indirect reference.
- java.lang.StringgetIndirectReference(java.lang.Object directReference) - -
-          Get a safe indirect reference to use in place of a potentially sensitive - direct object reference.
- java.util.Iteratoriterator() - -
-          Get an iterator through the direct object references.
- java.lang.StringremoveDirectReference(java.lang.Object direct) - -
-          Remove a direct reference and the corresponding indirect reference.
- voidupdate(java.util.Set directReferences) - -
-          This preserves any existing mappings for items that are still in the new - list.
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-IntegerAccessReferenceMap

-
-public IntegerAccessReferenceMap()
-
-
This AccessReferenceMap implementation uses integers to - create a layer of indirection. -

-

-
- -

-IntegerAccessReferenceMap

-
-public IntegerAccessReferenceMap(java.util.Set directReferences)
-
-
Instantiates a new access reference map. -

-

Parameters:
directReferences - the direct references
- - - - - - - - -
-Method Detail
- -

-iterator

-
-public java.util.Iterator iterator()
-
-
Description copied from interface: AccessReferenceMap
-
Get an iterator through the direct object references. No guarantee is made as - to the order of items returned. -

-

-
Specified by:
iterator in interface AccessReferenceMap
-
-
- -
Returns:
the iterator
-
-
-
- -

-addDirectReference

-
-public java.lang.String addDirectReference(java.lang.Object direct)
-
-
Adds a direct reference and a new indirect reference, overwriting any existing values. -

-

-
Specified by:
addDirectReference in interface AccessReferenceMap
-
-
-
Parameters:
direct - -
Returns:
the corresponding indirect reference
-
-
-
- -

-removeDirectReference

-
-public java.lang.String removeDirectReference(java.lang.Object direct)
-                                       throws AccessControlException
-
-
Remove a direct reference and the corresponding indirect reference. -

-

-
Specified by:
removeDirectReference in interface AccessReferenceMap
-
-
-
Parameters:
direct - -
Returns:
the corresponding indirect reference -
Throws: -
AccessControlException
-
-
-
- -

-update

-
-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. -

-

-
Specified by:
update in interface AccessReferenceMap
-
-
-
Parameters:
directReferences - the direct references
-
-
-
- -

-getIndirectReference

-
-public java.lang.String getIndirectReference(java.lang.Object directReference)
-
-
Description copied from interface: AccessReferenceMap
-
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. -

-

-
Specified by:
getIndirectReference in interface AccessReferenceMap
-
-
-
Parameters:
directReference - the direct reference -
Returns:
the indirect reference
-
-
-
- -

-getDirectReference

-
-public java.lang.Object getDirectReference(java.lang.String indirectReference)
-                                    throws AccessControlException
-
-
Description copied from interface: AccessReferenceMap
-
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. -

-

-
Specified by:
getDirectReference in interface AccessReferenceMap
-
-
-
Parameters:
indirectReference - the indirect reference -
Returns:
the direct reference -
Throws: -
AccessControlException - if no direct reference exists for the - specified indirect reference
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/IntegerAccessReferenceMapTest.html b/javadoc/org/owasp/esapi/reference/IntegerAccessReferenceMapTest.html deleted file mode 100644 index 6f33dfe6d..000000000 --- a/javadoc/org/owasp/esapi/reference/IntegerAccessReferenceMapTest.html +++ /dev/null @@ -1,428 +0,0 @@ - - - - - - -IntegerAccessReferenceMapTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class IntegerAccessReferenceMapTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.reference.IntegerAccessReferenceMapTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class IntegerAccessReferenceMapTest
extends junit.framework.TestCase
- -

-The Class AccessReferenceMapTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
IntegerAccessReferenceMapTest(java.lang.String testName) - -
-          Instantiates a new access reference map test.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestAddDirectReference() - -
-           
- voidtestGetDirectReference() - -
-          Test of getDirectReference method, of class - org.owasp.esapi.AccessReferenceMap.
- voidtestGetIndirectReference() - -
-          Test of getIndirectReference method, of class - org.owasp.esapi.AccessReferenceMap.
- voidtestIterator() - -
-          Test of iterator method, of class org.owasp.esapi.AccessReferenceMap.
- voidtestRemoveDirectReference() - -
-           
- voidtestUpdate() - -
-          Test of update method, of class org.owasp.esapi.AccessReferenceMap.
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-IntegerAccessReferenceMapTest

-
-public IntegerAccessReferenceMapTest(java.lang.String testName)
-
-
Instantiates a new access reference map test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testUpdate

-
-public void testUpdate()
-                throws AuthenticationException,
-                       EncryptionException
-
-
Test of update method, of class org.owasp.esapi.AccessReferenceMap. -

-

- -
Throws: -
AuthenticationException - the authentication exception -
EncryptionException
-
-
-
- -

-testIterator

-
-public void testIterator()
-
-
Test of iterator method, of class org.owasp.esapi.AccessReferenceMap. -

-

-
-
-
-
- -

-testGetIndirectReference

-
-public void testGetIndirectReference()
-
-
Test of getIndirectReference method, of class - org.owasp.esapi.AccessReferenceMap. -

-

-
-
-
-
- -

-testGetDirectReference

-
-public void testGetDirectReference()
-                            throws AccessControlException
-
-
Test of getDirectReference method, of class - org.owasp.esapi.AccessReferenceMap. -

-

- -
Throws: -
AccessControlException - the access control exception
-
-
-
- -

-testAddDirectReference

-
-public void testAddDirectReference()
-                            throws AccessControlException
-
-
- -
Throws: -
AccessControlException
-
-
-
- -

-testRemoveDirectReference

-
-public void testRemoveDirectReference()
-                               throws AccessControlException
-
-
- -
Throws: -
AccessControlException
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/IntrusionDetectorTest.html b/javadoc/org/owasp/esapi/reference/IntrusionDetectorTest.html deleted file mode 100644 index 305bf2451..000000000 --- a/javadoc/org/owasp/esapi/reference/IntrusionDetectorTest.html +++ /dev/null @@ -1,336 +0,0 @@ - - - - - - -IntrusionDetectorTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class IntrusionDetectorTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.reference.IntrusionDetectorTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class IntrusionDetectorTest
extends junit.framework.TestCase
- -

-The Class IntrusionDetectorTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
IntrusionDetectorTest(java.lang.String testName) - -
-          Instantiates a new intrusion detector test.
-  - - - - - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestAddEvent() - -
-          Test of addEvent method, of class org.owasp.esapi.IntrusionDetector.
- voidtestAddException() - -
-          Test of addException method, of class org.owasp.esapi.IntrusionDetector.
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-IntrusionDetectorTest

-
-public IntrusionDetectorTest(java.lang.String testName)
-
-
Instantiates a new intrusion detector test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testAddException

-
-public void testAddException()
-                      throws AuthenticationException
-
-
Test of addException method, of class org.owasp.esapi.IntrusionDetector. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testAddEvent

-
-public void testAddEvent()
-                  throws AuthenticationException
-
-
Test of addEvent method, of class org.owasp.esapi.IntrusionDetector. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/JSEEncryptor.html b/javadoc/org/owasp/esapi/reference/JSEEncryptor.html deleted file mode 100644 index b381563f2..000000000 --- a/javadoc/org/owasp/esapi/reference/JSEEncryptor.html +++ /dev/null @@ -1,551 +0,0 @@ - - - - - - -JSEEncryptor - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class JSEEncryptor

-
-java.lang.Object
-  extended byorg.owasp.esapi.reference.JSEEncryptor
-
-
-
All Implemented Interfaces:
Encryptor
-
-
-
-
public class JSEEncryptor
extends java.lang.Object
implements Encryptor
- -

-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
-
See Also:
Encryptor
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
JSEEncryptor() - -
-           
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- java.lang.Stringdecrypt(java.lang.String ciphertext) - -
-          Decrypts the provided ciphertext string (encrypted with the encrypt - method) and returns a plaintext string.
- java.lang.Stringencrypt(java.lang.String plaintext) - -
-          Encrypts the provided plaintext and returns a ciphertext string.
- longgetRelativeTimeStamp(long offset) - -
-          Gets an absolute timestamp representing an offset from the current time to be used by - other functions in the library.
- longgetTimeStamp() - -
-          Gets a timestamp representing the current date and time to be used by - other functions in the library.
- java.lang.Stringhash(java.lang.String plaintext, - java.lang.String salt) - -
-          Hashes the data using the specified algorithm and the Java MessageDigest class.
- java.lang.Stringseal(java.lang.String data, - long expiration) - -
-          Creates a seal that binds a set of data and includes an expiration timestamp.
- java.lang.Stringsign(java.lang.String data) - -
-          Create a digital signature for the provided data and return it in a - string.
- java.lang.Stringunseal(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.
- booleanverifySeal(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.
- booleanverifySignature(java.lang.String signature, - java.lang.String data) - -
-          Verifies a digital signature (created with the sign method) and returns - the boolean result.
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-JSEEncryptor

-
-public JSEEncryptor()
-
-
- - - - - - - - -
-Method Detail
- -

-hash

-
-public java.lang.String hash(java.lang.String plaintext,
-                             java.lang.String salt)
-                      throws EncryptionException
-
-
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. -

-

-
Specified by:
hash in interface Encryptor
-
-
-
Parameters:
plaintext - the plaintext
salt - the salt -
Returns:
the string -
Throws: -
EncryptionException - the encryption exception
See Also:
Encryptor.hash(java.lang.String,java.lang.String)
-
-
-
- -

-encrypt

-
-public java.lang.String encrypt(java.lang.String plaintext)
-                         throws EncryptionException
-
-
Description copied from interface: Encryptor
-
Encrypts the provided plaintext and returns a ciphertext string. -

-

-
Specified by:
encrypt in interface Encryptor
-
-
-
Parameters:
plaintext - the plaintext -
Returns:
the string -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-decrypt

-
-public java.lang.String decrypt(java.lang.String ciphertext)
-                         throws EncryptionException
-
-
Description copied from interface: Encryptor
-
Decrypts the provided ciphertext string (encrypted with the encrypt - method) and returns a plaintext string. -

-

-
Specified by:
decrypt in interface Encryptor
-
-
-
Parameters:
ciphertext - the ciphertext -
Returns:
the string -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-sign

-
-public java.lang.String sign(java.lang.String data)
-                      throws EncryptionException
-
-
Description copied from interface: Encryptor
-
Create a digital signature for the provided data and return it in a - string. -

-

-
Specified by:
sign in interface Encryptor
-
-
-
Parameters:
data - the data -
Returns:
the string -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-verifySignature

-
-public boolean verifySignature(java.lang.String signature,
-                               java.lang.String data)
-
-
Description copied from interface: Encryptor
-
Verifies a digital signature (created with the sign method) and returns - the boolean result. -

-

-
Specified by:
verifySignature in interface Encryptor
-
-
-
Parameters:
signature - the signature
data - the data -
Returns:
true, if successful
-
-
-
- -

-seal

-
-public java.lang.String seal(java.lang.String data,
-                             long expiration)
-                      throws IntegrityException
-
-
Description copied from interface: Encryptor
-
Creates a seal that binds a set of data and includes an expiration timestamp. -

-

-
Specified by:
seal in interface Encryptor
-
-
-
Parameters:
data - the data
expiration - the absolute expiration date of the data, expressed as seconds since the epoch -
Returns:
the string -
Throws: -
IntegrityException
-
-
-
- -

-unseal

-
-public java.lang.String unseal(java.lang.String seal)
-                        throws EncryptionException
-
-
Description copied from interface: Encryptor
-
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. -

-

-
Specified by:
unseal in interface Encryptor
-
-
-
Parameters:
seal - the sealed data -
Returns:
the original data -
Throws: -
EncryptionException
-
-
-
- -

-verifySeal

-
-public boolean verifySeal(java.lang.String seal)
-
-
Description copied from interface: Encryptor
-
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. -

-

-
Specified by:
verifySeal in interface Encryptor
-
-
-
Parameters:
seal - the seal -
Returns:
true if the seal is valid
-
-
-
- -

-getTimeStamp

-
-public long getTimeStamp()
-
-
Description copied from interface: Encryptor
-
Gets a timestamp representing the current date and time to be used by - other functions in the library. -

-

-
Specified by:
getTimeStamp in interface Encryptor
-
-
- -
Returns:
the timestamp
-
-
-
- -

-getRelativeTimeStamp

-
-public long getRelativeTimeStamp(long offset)
-
-
Description copied from interface: Encryptor
-
Gets an absolute timestamp representing an offset from the current time to be used by - other functions in the library. -

-

-
Specified by:
getRelativeTimeStamp in interface Encryptor
-
-
- -
Returns:
the absolute timestamp
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/JavaEncryptor.html b/javadoc/org/owasp/esapi/reference/JavaEncryptor.html deleted file mode 100644 index 0aa3d5dce..000000000 --- a/javadoc/org/owasp/esapi/reference/JavaEncryptor.html +++ /dev/null @@ -1,551 +0,0 @@ - - - - - - -JavaEncryptor - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class JavaEncryptor

-
-java.lang.Object
-  extended byorg.owasp.esapi.reference.JavaEncryptor
-
-
-
All Implemented Interfaces:
Encryptor
-
-
-
-
public class JavaEncryptor
extends java.lang.Object
implements Encryptor
- -

-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
-
See Also:
Encryptor
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
JavaEncryptor() - -
-           
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- java.lang.Stringdecrypt(java.lang.String ciphertext) - -
-          Decrypts the provided ciphertext string (encrypted with the encrypt - method) and returns a plaintext string.
- java.lang.Stringencrypt(java.lang.String plaintext) - -
-          Encrypts the provided plaintext and returns a ciphertext string.
- longgetRelativeTimeStamp(long offset) - -
-          Gets an absolute timestamp representing an offset from the current time to be used by - other functions in the library.
- longgetTimeStamp() - -
-          Gets a timestamp representing the current date and time to be used by - other functions in the library.
- java.lang.Stringhash(java.lang.String plaintext, - java.lang.String salt) - -
-          Hashes the data using the specified algorithm and the Java MessageDigest class.
- java.lang.Stringseal(java.lang.String data, - long expiration) - -
-          Creates a seal that binds a set of data and includes an expiration timestamp.
- java.lang.Stringsign(java.lang.String data) - -
-          Create a digital signature for the provided data and return it in a - string.
- java.lang.Stringunseal(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.
- booleanverifySeal(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.
- booleanverifySignature(java.lang.String signature, - java.lang.String data) - -
-          Verifies a digital signature (created with the sign method) and returns - the boolean result.
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-JavaEncryptor

-
-public JavaEncryptor()
-
-
- - - - - - - - -
-Method Detail
- -

-hash

-
-public java.lang.String hash(java.lang.String plaintext,
-                             java.lang.String salt)
-                      throws EncryptionException
-
-
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. -

-

-
Specified by:
hash in interface Encryptor
-
-
-
Parameters:
plaintext - the plaintext String to encrypt
salt - the salt -
Returns:
the encrypted hash of 'plaintext' stored as a String -
Throws: -
EncryptionException - the encryption exception
See Also:
Encryptor.hash(java.lang.String,java.lang.String)
-
-
-
- -

-encrypt

-
-public java.lang.String encrypt(java.lang.String plaintext)
-                         throws EncryptionException
-
-
Description copied from interface: Encryptor
-
Encrypts the provided plaintext and returns a ciphertext string. -

-

-
Specified by:
encrypt in interface Encryptor
-
-
-
Parameters:
plaintext - the plaintext String to encrypt -
Returns:
the encrypted String -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-decrypt

-
-public java.lang.String decrypt(java.lang.String ciphertext)
-                         throws EncryptionException
-
-
Description copied from interface: Encryptor
-
Decrypts the provided ciphertext string (encrypted with the encrypt - method) and returns a plaintext string. -

-

-
Specified by:
decrypt in interface Encryptor
-
-
-
Parameters:
ciphertext - the ciphertext -
Returns:
the decrypted ciphertext -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-sign

-
-public java.lang.String sign(java.lang.String data)
-                      throws EncryptionException
-
-
Description copied from interface: Encryptor
-
Create a digital signature for the provided data and return it in a - string. -

-

-
Specified by:
sign in interface Encryptor
-
-
-
Parameters:
data - the data to sign -
Returns:
the digital signature stored as a String -
Throws: -
EncryptionException - the encryption exception
-
-
-
- -

-verifySignature

-
-public boolean verifySignature(java.lang.String signature,
-                               java.lang.String data)
-
-
Description copied from interface: Encryptor
-
Verifies a digital signature (created with the sign method) and returns - the boolean result. -

-

-
Specified by:
verifySignature in interface Encryptor
-
-
-
Parameters:
signature - the signature to verify
data - the data to verify -
Returns:
true, if the signature is verified
-
-
-
- -

-seal

-
-public java.lang.String seal(java.lang.String data,
-                             long expiration)
-                      throws IntegrityException
-
-
Description copied from interface: Encryptor
-
Creates a seal that binds a set of data and includes an expiration timestamp. -

-

-
Specified by:
seal in interface Encryptor
-
-
-
Parameters:
data - the data to seal
expiration - the absolute expiration date of the data, expressed as seconds since the epoch -
Returns:
the seal -
Throws: -
IntegrityException
-
-
-
- -

-unseal

-
-public java.lang.String unseal(java.lang.String seal)
-                        throws EncryptionException
-
-
Description copied from interface: Encryptor
-
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. -

-

-
Specified by:
unseal in interface Encryptor
-
-
-
Parameters:
seal - the sealed data -
Returns:
the original data -
Throws: -
EncryptionException
-
-
-
- -

-verifySeal

-
-public boolean verifySeal(java.lang.String seal)
-
-
Description copied from interface: Encryptor
-
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. -

-

-
Specified by:
verifySeal in interface Encryptor
-
-
-
Parameters:
seal - the seal -
Returns:
true, if the seal is valid
-
-
-
- -

-getTimeStamp

-
-public long getTimeStamp()
-
-
Description copied from interface: Encryptor
-
Gets a timestamp representing the current date and time to be used by - other functions in the library. -

-

-
Specified by:
getTimeStamp in interface Encryptor
-
-
- -
Returns:
the timestamp
-
-
-
- -

-getRelativeTimeStamp

-
-public long getRelativeTimeStamp(long offset)
-
-
Description copied from interface: Encryptor
-
Gets an absolute timestamp representing an offset from the current time to be used by - other functions in the library. -

-

-
Specified by:
getRelativeTimeStamp in interface Encryptor
-
-
-
Parameters:
offset - the offset to add to the current time -
Returns:
the absolute timestamp
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/JavaLogFactory.html b/javadoc/org/owasp/esapi/reference/JavaLogFactory.html deleted file mode 100644 index 0444b043c..000000000 --- a/javadoc/org/owasp/esapi/reference/JavaLogFactory.html +++ /dev/null @@ -1,291 +0,0 @@ - - - - - - -JavaLogFactory - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class JavaLogFactory

-
-java.lang.Object
-  extended byorg.owasp.esapi.reference.JavaLogFactory
-
-
-
All Implemented Interfaces:
LogFactory
-
-
-
-
public class JavaLogFactory
extends java.lang.Object
implements LogFactory
- -

-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
-
See Also:
Logger
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
JavaLogFactory(java.lang.String applicationName) - -
-           
-  - - - - - - - - - - - - - - - -
-Method Summary
- LoggergetLogger(java.lang.Class clazz) - -
-           
- LoggergetLogger(java.lang.String name) - -
-           
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-JavaLogFactory

-
-public JavaLogFactory(java.lang.String applicationName)
-
-
- - - - - - - - -
-Method Detail
- -

-getLogger

-
-public Logger getLogger(java.lang.Class clazz)
-
-
-
Specified by:
getLogger in interface LogFactory
-
-
-
-
-
-
- -

-getLogger

-
-public Logger getLogger(java.lang.String name)
-
-
-
Specified by:
getLogger in interface LogFactory
-
-
-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/LoggerTest.html b/javadoc/org/owasp/esapi/reference/LoggerTest.html deleted file mode 100644 index 19bd11abc..000000000 --- a/javadoc/org/owasp/esapi/reference/LoggerTest.html +++ /dev/null @@ -1,442 +0,0 @@ - - - - - - -LoggerTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class LoggerTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.reference.LoggerTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class LoggerTest
extends junit.framework.TestCase
- -

-The Class LoggerTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
LoggerTest(java.lang.String testName) - -
-          Instantiates a new logger test.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestDebug() - -
-          Test of logDebug method, of class org.owasp.esapi.Logger.
- voidtestError() - -
-          Test of logError method, of class org.owasp.esapi.Logger.
- voidtestFatal() - -
-          Test of logCritical method, of class org.owasp.esapi.Logger.
- voidtestInfo() - -
-          Test of logSuccess method, of class org.owasp.esapi.Logger.
- voidtestLogHTTPRequest() - -
-          Test of logHTTPRequest method, of class org.owasp.esapi.Logger.
- voidtestTrace() - -
-          Test of logTrace method, of class org.owasp.esapi.Logger.
- voidtestWarning() - -
-          Test of logWarning method, of class org.owasp.esapi.Logger.
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-LoggerTest

-
-public LoggerTest(java.lang.String testName)
-
-
Instantiates a new logger test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testLogHTTPRequest

-
-public void testLogHTTPRequest()
-                        throws ValidationException,
-                               java.io.IOException,
-                               AuthenticationException
-
-
Test of logHTTPRequest method, of class org.owasp.esapi.Logger. -

-

- -
Throws: -
ValidationException - the validation exception -
java.io.IOException - Signals that an I/O exception has occurred. -
AuthenticationException - the authentication exception
-
-
-
- -

-testInfo

-
-public void testInfo()
-
-
Test of logSuccess method, of class org.owasp.esapi.Logger. -

-

-
-
-
-
- -

-testTrace

-
-public void testTrace()
-
-
Test of logTrace method, of class org.owasp.esapi.Logger. -

-

-
-
-
-
- -

-testDebug

-
-public void testDebug()
-
-
Test of logDebug method, of class org.owasp.esapi.Logger. -

-

-
-
-
-
- -

-testError

-
-public void testError()
-
-
Test of logError method, of class org.owasp.esapi.Logger. -

-

-
-
-
-
- -

-testWarning

-
-public void testWarning()
-
-
Test of logWarning method, of class org.owasp.esapi.Logger. -

-

-
-
-
-
- -

-testFatal

-
-public void testFatal()
-
-
Test of logCritical method, of class org.owasp.esapi.Logger. -

-

-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/RandomAccessReferenceMap.html b/javadoc/org/owasp/esapi/reference/RandomAccessReferenceMap.html deleted file mode 100644 index fd1fa3d22..000000000 --- a/javadoc/org/owasp/esapi/reference/RandomAccessReferenceMap.html +++ /dev/null @@ -1,444 +0,0 @@ - - - - - - -RandomAccessReferenceMap - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class RandomAccessReferenceMap

-
-java.lang.Object
-  extended byorg.owasp.esapi.reference.RandomAccessReferenceMap
-
-
-
All Implemented Interfaces:
AccessReferenceMap
-
-
-
-
public class RandomAccessReferenceMap
extends java.lang.Object
implements AccessReferenceMap
- -

-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. -

- -

-

-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
See Also:
AccessReferenceMap
-
- -

- - - - - - - - - - - - - - - - - - - -
-Constructor Summary
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.StringaddDirectReference(java.lang.Object direct) - -
-          Adds a direct reference and a new random indirect reference, overwriting any existing values.
- java.lang.ObjectgetDirectReference(java.lang.String indirectReference) - -
-          Get the original direct object reference from an indirect reference.
- java.lang.StringgetIndirectReference(java.lang.Object directReference) - -
-          Get a safe indirect reference to use in place of a potentially sensitive - direct object reference.
- java.util.Iteratoriterator() - -
-          Get an iterator through the direct object references.
- java.lang.StringremoveDirectReference(java.lang.Object direct) - -
-          Remove a direct reference and the corresponding indirect reference.
- voidupdate(java.util.Set directReferences) - -
-          This preserves any existing mappings for items that are still in the new - list.
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-RandomAccessReferenceMap

-
-public RandomAccessReferenceMap()
-
-
This AccessReferenceMap implementation uses short random strings to - create a layer of indirection. Other possible implementations would use - simple integers as indirect references. -

-

-
- -

-RandomAccessReferenceMap

-
-public RandomAccessReferenceMap(java.util.Set directReferences)
-
-
Instantiates a new access reference map. -

-

Parameters:
directReferences - the direct references
- - - - - - - - -
-Method Detail
- -

-iterator

-
-public java.util.Iterator iterator()
-
-
Description copied from interface: AccessReferenceMap
-
Get an iterator through the direct object references. No guarantee is made as - to the order of items returned. -

-

-
Specified by:
iterator in interface AccessReferenceMap
-
-
- -
Returns:
the iterator
-
-
-
- -

-addDirectReference

-
-public java.lang.String addDirectReference(java.lang.Object direct)
-
-
Adds a direct reference and a new random indirect reference, overwriting any existing values. -

-

-
Specified by:
addDirectReference in interface AccessReferenceMap
-
-
-
Parameters:
direct - -
Returns:
the corresponding indirect reference
-
-
-
- -

-removeDirectReference

-
-public java.lang.String removeDirectReference(java.lang.Object direct)
-                                       throws AccessControlException
-
-
Remove a direct reference and the corresponding indirect reference. -

-

-
Specified by:
removeDirectReference in interface AccessReferenceMap
-
-
-
Parameters:
direct - -
Returns:
the corresponding indirect reference -
Throws: -
AccessControlException
-
-
-
- -

-update

-
-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. -

-

-
Specified by:
update in interface AccessReferenceMap
-
-
-
Parameters:
directReferences - the direct references
-
-
-
- -

-getIndirectReference

-
-public java.lang.String getIndirectReference(java.lang.Object directReference)
-
-
Description copied from interface: AccessReferenceMap
-
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. -

-

-
Specified by:
getIndirectReference in interface AccessReferenceMap
-
-
-
Parameters:
directReference - the direct reference -
Returns:
the indirect reference
-
-
-
- -

-getDirectReference

-
-public java.lang.Object getDirectReference(java.lang.String indirectReference)
-                                    throws AccessControlException
-
-
Description copied from interface: AccessReferenceMap
-
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. -

-

-
Specified by:
getDirectReference in interface AccessReferenceMap
-
-
-
Parameters:
indirectReference - the indirect reference -
Returns:
the direct reference -
Throws: -
AccessControlException - if no direct reference exists for the - specified indirect reference
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/RandomizerTest.html b/javadoc/org/owasp/esapi/reference/RandomizerTest.html deleted file mode 100644 index 05386470c..000000000 --- a/javadoc/org/owasp/esapi/reference/RandomizerTest.html +++ /dev/null @@ -1,375 +0,0 @@ - - - - - - -RandomizerTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class RandomizerTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.reference.RandomizerTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class RandomizerTest
extends junit.framework.TestCase
- -

-The Class RandomizerTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
RandomizerTest(java.lang.String testName) - -
-          Instantiates a new randomizer test.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestGetRandomGUID() - -
-          Test of getRandomGUID method, of class org.owasp.esapi.Randomizer.
- voidtestGetRandomInteger() - -
-          Test of getRandomInteger method, of class org.owasp.esapi.Randomizer.
- voidtestGetRandomReal() - -
-          Test of getRandomReal method, of class org.owasp.esapi.Randomizer.
- voidtestGetRandomString() - -
-          Test of getRandomString method, of class org.owasp.esapi.Randomizer.
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-RandomizerTest

-
-public RandomizerTest(java.lang.String testName)
-
-
Instantiates a new randomizer test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testGetRandomString

-
-public void testGetRandomString()
-
-
Test of getRandomString method, of class org.owasp.esapi.Randomizer. -

-

-
-
-
-
- -

-testGetRandomInteger

-
-public void testGetRandomInteger()
-
-
Test of getRandomInteger method, of class org.owasp.esapi.Randomizer. -

-

-
-
-
-
- -

-testGetRandomReal

-
-public void testGetRandomReal()
-
-
Test of getRandomReal method, of class org.owasp.esapi.Randomizer. -

-

-
-
-
-
- -

-testGetRandomGUID

-
-public void testGetRandomGUID()
-                       throws EncryptionException
-
-
Test of getRandomGUID method, of class org.owasp.esapi.Randomizer. -

-

- -
Throws: -
EncryptionException
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/SafeFileTest.html b/javadoc/org/owasp/esapi/reference/SafeFileTest.html deleted file mode 100644 index 98c96b9af..000000000 --- a/javadoc/org/owasp/esapi/reference/SafeFileTest.html +++ /dev/null @@ -1,495 +0,0 @@ - - - - - - -SafeFileTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class SafeFileTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.reference.SafeFileTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class SafeFileTest
extends junit.framework.TestCase
- -

-The Class ExecutorTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
SafeFileTest(java.lang.String testName) - -
-          Instantiates a new executor test.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestAlternateDataStream() - -
-           
- voidtestCreateSafeFile() - -
-          Test of executeOSCommand method, of class org.owasp.esapi.Executor
- voidtestCreateSafeFileParentConstructor() - -
-           
- voidtestCreateSafeFileURIConstructor() - -
-           
- voidtestJavaDirInjection() - -
-           
- voidtestJavaFileInjection() - -
-           
- voidtestMultipleJavaFileInjection() - -
-           
- voidtestNormalPercentEncodedFileInjection() - -
-           
- voidtestWeirdPercentEncodedFileInjection() - -
-           
-static java.lang.StringtoHex(byte b) - -
-           
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-SafeFileTest

-
-public SafeFileTest(java.lang.String testName)
-
-
Instantiates a new executor test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testJavaFileInjection

-
-public void testJavaFileInjection()
-
-
-
-
-
-
- -

-testMultipleJavaFileInjection

-
-public void testMultipleJavaFileInjection()
-
-
-
-
-
-
- -

-testAlternateDataStream

-
-public void testAlternateDataStream()
-
-
-
-
-
-
- -

-testJavaDirInjection

-
-public void testJavaDirInjection()
-
-
-
-
-
-
- -

-toHex

-
-public static java.lang.String toHex(byte b)
-
-
-
-
-
-
- -

-testNormalPercentEncodedFileInjection

-
-public void testNormalPercentEncodedFileInjection()
-                                           throws java.lang.Exception
-
-
- -
Throws: -
java.lang.Exception
-
-
-
- -

-testWeirdPercentEncodedFileInjection

-
-public void testWeirdPercentEncodedFileInjection()
-                                          throws java.lang.Exception
-
-
- -
Throws: -
java.lang.Exception
-
-
-
- -

-testCreateSafeFile

-
-public void testCreateSafeFile()
-                        throws java.lang.Exception
-
-
Test of executeOSCommand method, of class org.owasp.esapi.Executor -

-

- -
Throws: -
java.lang.Exception - the exception
-
-
-
- -

-testCreateSafeFileParentConstructor

-
-public void testCreateSafeFileParentConstructor()
-                                         throws java.lang.Exception
-
-
- -
Throws: -
java.lang.Exception
-
-
-
- -

-testCreateSafeFileURIConstructor

-
-public void testCreateSafeFileURIConstructor()
-                                      throws java.lang.Exception
-
-
- -
Throws: -
java.lang.Exception
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/UserTest.html b/javadoc/org/owasp/esapi/reference/UserTest.html deleted file mode 100644 index 336f2f556..000000000 --- a/javadoc/org/owasp/esapi/reference/UserTest.html +++ /dev/null @@ -1,966 +0,0 @@ - - - - - - -UserTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class UserTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.reference.UserTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class UserTest
extends junit.framework.TestCase
- -

-The Class UserTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
UserTest(java.lang.String testName) - -
-          Instantiates a new user test.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestAddRole() - -
-          Test of testAddRole method, of class org.owasp.esapi.User.
- voidtestAddRoles() - -
-          Test of addRoles method, of class org.owasp.esapi.User.
- voidtestChangePassword() - -
-          Test of changePassword method, of class org.owasp.esapi.User.
- voidtestDisable() - -
-          Test of disable method, of class org.owasp.esapi.User.
- voidtestEnable() - -
-          Test of enable method, of class org.owasp.esapi.User.
- voidtestFailedLoginLockout() - -
-          Test of failedLoginCount lockout, of class org.owasp.esapi.User.
- voidtestGetAccountName() - -
-          Test of getAccountName method, of class org.owasp.esapi.User.
- voidtestGetLastFailedLoginTime() - -
-          Test get last failed login time.
- voidtestGetLastLoginTime() - -
-          Test get last login time.
- voidtestGetLastPasswordChangeTime() - -
-          Test of getLastPasswordChangeTime method, of class org.owasp.esapi.User.
- voidtestGetRoles() - -
-          Test of getRoles method, of class org.owasp.esapi.User.
- voidtestGetScreenName() - -
-          Test of xxx method, of class org.owasp.esapi.User.
- voidtestIncrementFailedLoginCount() - -
-          Test of incrementFailedLoginCount method, of class org.owasp.esapi.User.
- voidtestIsEnabled() - -
-          Test of isEnabled method, of class org.owasp.esapi.User.
- voidtestIsInRole() - -
-          Test of isInRole method, of class org.owasp.esapi.User.
- voidtestIsLocked() - -
-          Test of xxx method, of class org.owasp.esapi.User.
- voidtestIsSessionAbsoluteTimeout() - -
-          Test of isSessionAbsoluteTimeout method, of class - org.owasp.esapi.IntrusionDetector.
- voidtestIsSessionTimeout() - -
-          Test of isSessionTimeout method, of class - org.owasp.esapi.IntrusionDetector.
- voidtestLock() - -
-          Test of lockAccount method, of class org.owasp.esapi.User.
- voidtestLoginWithPassword() - -
-          Test of loginWithPassword method, of class org.owasp.esapi.User.
- voidtestLogout() - -
-          Test of logout method, of class org.owasp.esapi.User.
- voidtestRemoveRole() - -
-          Test of testRemoveRole method, of class org.owasp.esapi.User.
- voidtestResetCSRFToken() - -
-          Test of testResetCSRFToken method, of class org.owasp.esapi.User.
- voidtestSetAccountName() - -
-          Test of setAccountName method, of class org.owasp.esapi.User.
- voidtestSetExpirationTime() - -
-          Test of setExpirationTime method, of class org.owasp.esapi.User.
- voidtestSetRoles() - -
-          Test of setRoles method, of class org.owasp.esapi.User.
- voidtestSetScreenName() - -
-          Test of setScreenName method, of class org.owasp.esapi.User.
- voidtestUnlock() - -
-          Test of unlockAccount method, of class org.owasp.esapi.User.
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-UserTest

-
-public UserTest(java.lang.String testName)
-
-
Instantiates a new user test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testAddRole

-
-public void testAddRole()
-                 throws java.lang.Exception
-
-
Test of testAddRole method, of class org.owasp.esapi.User. -

-

- -
Throws: -
java.lang.Exception
-
-
-
- -

-testAddRoles

-
-public void testAddRoles()
-                  throws AuthenticationException
-
-
Test of addRoles method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testChangePassword

-
-public void testChangePassword()
-                        throws java.lang.Exception
-
-
Test of changePassword method, of class org.owasp.esapi.User. -

-

- -
Throws: -
java.lang.Exception - the exception
-
-
-
- -

-testDisable

-
-public void testDisable()
-                 throws AuthenticationException
-
-
Test of disable method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testEnable

-
-public void testEnable()
-                throws AuthenticationException
-
-
Test of enable method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testFailedLoginLockout

-
-public void testFailedLoginLockout()
-                            throws AuthenticationException,
-                                   EncryptionException
-
-
Test of failedLoginCount lockout, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception -
EncryptionException
-
-
-
- -

-testGetAccountName

-
-public void testGetAccountName()
-                        throws AuthenticationException
-
-
Test of getAccountName method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testGetLastFailedLoginTime

-
-public void testGetLastFailedLoginTime()
-                                throws java.lang.Exception
-
-
Test get last failed login time. -

-

- -
Throws: -
java.lang.Exception - the exception
-
-
-
- -

-testGetLastLoginTime

-
-public void testGetLastLoginTime()
-                          throws java.lang.Exception
-
-
Test get last login time. -

-

- -
Throws: -
java.lang.Exception - the exception
-
-
-
- -

-testGetLastPasswordChangeTime

-
-public void testGetLastPasswordChangeTime()
-                                   throws java.lang.Exception
-
-
Test of getLastPasswordChangeTime method, of class org.owasp.esapi.User. -

-

- -
Throws: -
java.lang.Exception - the exception
-
-
-
- -

-testGetRoles

-
-public void testGetRoles()
-                  throws java.lang.Exception
-
-
Test of getRoles method, of class org.owasp.esapi.User. -

-

- -
Throws: -
java.lang.Exception
-
-
-
- -

-testGetScreenName

-
-public void testGetScreenName()
-                       throws AuthenticationException
-
-
Test of xxx method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testIncrementFailedLoginCount

-
-public void testIncrementFailedLoginCount()
-                                   throws AuthenticationException
-
-
Test of incrementFailedLoginCount method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testIsEnabled

-
-public void testIsEnabled()
-                   throws AuthenticationException
-
-
Test of isEnabled method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testIsInRole

-
-public void testIsInRole()
-                  throws AuthenticationException
-
-
Test of isInRole method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testIsLocked

-
-public void testIsLocked()
-                  throws AuthenticationException
-
-
Test of xxx method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testIsSessionAbsoluteTimeout

-
-public void testIsSessionAbsoluteTimeout()
-                                  throws AuthenticationException
-
-
Test of isSessionAbsoluteTimeout method, of class - org.owasp.esapi.IntrusionDetector. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testIsSessionTimeout

-
-public void testIsSessionTimeout()
-                          throws AuthenticationException
-
-
Test of isSessionTimeout method, of class - org.owasp.esapi.IntrusionDetector. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testLock

-
-public void testLock()
-              throws AuthenticationException
-
-
Test of lockAccount method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testLoginWithPassword

-
-public void testLoginWithPassword()
-                           throws AuthenticationException
-
-
Test of loginWithPassword method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testLogout

-
-public void testLogout()
-                throws AuthenticationException
-
-
Test of logout method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testRemoveRole

-
-public void testRemoveRole()
-                    throws AuthenticationException
-
-
Test of testRemoveRole method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testResetCSRFToken

-
-public void testResetCSRFToken()
-                        throws AuthenticationException
-
-
Test of testResetCSRFToken method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testSetAccountName

-
-public void testSetAccountName()
-                        throws AuthenticationException
-
-
Test of setAccountName method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException
-
-
-
- -

-testSetExpirationTime

-
-public void testSetExpirationTime()
-                           throws java.lang.Exception
-
-
Test of setExpirationTime method, of class org.owasp.esapi.User. -

-

- -
Throws: -
java.lang.Exception
-
-
-
- -

-testSetRoles

-
-public void testSetRoles()
-                  throws AuthenticationException
-
-
Test of setRoles method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testSetScreenName

-
-public void testSetScreenName()
-                       throws AuthenticationException
-
-
Test of setScreenName method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
-
- -

-testUnlock

-
-public void testUnlock()
-                throws AuthenticationException
-
-
Test of unlockAccount method, of class org.owasp.esapi.User. -

-

- -
Throws: -
AuthenticationException - the authentication exception
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/ValidatorTest.html b/javadoc/org/owasp/esapi/reference/ValidatorTest.html deleted file mode 100644 index 66d5ca136..000000000 --- a/javadoc/org/owasp/esapi/reference/ValidatorTest.html +++ /dev/null @@ -1,605 +0,0 @@ - - - - - - -ValidatorTest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.reference -
-Class ValidatorTest

-
-java.lang.Object
-  extended byjunit.framework.Assert
-      extended byjunit.framework.TestCase
-          extended byorg.owasp.esapi.reference.ValidatorTest
-
-
-
All Implemented Interfaces:
junit.framework.Test
-
-
-
-
public class ValidatorTest
extends junit.framework.TestCase
- -

-The Class ValidatorTest. -

- -

-

-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
- -

- - - - - - - - - - - - - - - - -
-Constructor Summary
ValidatorTest(java.lang.String testName) - -
-          Instantiates a new validator test.
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
-static junit.framework.Testsuite() - -
-          Suite.
- voidtestGetValidDate() - -
-          Test of getValidDate method, of class org.owasp.esapi.Validator.
- voidtestGetValidSafeHTML() - -
-          Test of getValidSafeHTML method, of class org.owasp.esapi.Validator.
- voidtestIsValidCreditCard() - -
-          Test of isValidCreditCard method, of class org.owasp.esapi.Validator.
- voidtestIsValidDirectoryPath() - -
-          Test of isValidDirectoryPath method, of class org.owasp.esapi.Validator.
- voidtestIsValidFileContent() - -
-          Test of isValidFileContent method, of class org.owasp.esapi.Validator.
- voidtestIsValidFileName() - -
-          Test of isValidFileName method, of class org.owasp.esapi.Validator.
- voidtestIsValidFileUpload() - -
-          Test of isValidFileUpload method, of class org.owasp.esapi.Validator.
- voidtestisValidInput() - -
-          Test of isValidEmailAddress method, of class org.owasp.esapi.Validator.
- voidtestIsValidInteger() - -
-           
- voidtestIsValidListItem() - -
-          Test of isValidListItem method, of class org.owasp.esapi.Validator.
- voidtestIsValidNumber() - -
-          Test of isValidNumber method, of class org.owasp.esapi.Validator.
- voidtestIsValidParameterSet() - -
-          Test of isValidParameterSet method, of class org.owasp.esapi.Validator.
- voidtestIsValidPrintable() - -
-           
- voidtestIsValidSafeHTML() - -
-          Test of isValidSafeHTML method, of class org.owasp.esapi.Validator.
- voidtestSafeReadLine() - -
-          Test safe read line.
- - - - - - - -
Methods inherited from class junit.framework.TestCase
countTestCases, getName, run, run, runBare, setName, toString
- - - - - - - -
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-ValidatorTest

-
-public ValidatorTest(java.lang.String testName)
-
-
Instantiates a new validator test. -

-

Parameters:
testName - the test name
- - - - - - - - -
-Method Detail
- -

-suite

-
-public static junit.framework.Test suite()
-
-
Suite. -

-

- -
Returns:
the test
-
-
-
- -

-testIsValidCreditCard

-
-public void testIsValidCreditCard()
-
-
Test of isValidCreditCard method, of class org.owasp.esapi.Validator. -

-

-
-
-
-
- -

-testisValidInput

-
-public void testisValidInput()
-
-
Test of isValidEmailAddress method, of class org.owasp.esapi.Validator. -

-

-
-
-
-
- -

-testIsValidSafeHTML

-
-public void testIsValidSafeHTML()
-
-
Test of isValidSafeHTML method, of class org.owasp.esapi.Validator. -

-

-
-
-
-
- -

-testGetValidSafeHTML

-
-public void testGetValidSafeHTML()
-                          throws java.lang.Exception
-
-
Test of getValidSafeHTML method, of class org.owasp.esapi.Validator. -

-

- -
Throws: -
java.lang.Exception
-
-
-
- -

-testIsValidListItem

-
-public void testIsValidListItem()
-
-
Test of isValidListItem method, of class org.owasp.esapi.Validator. -

-

-
-
-
-
- -

-testIsValidNumber

-
-public void testIsValidNumber()
-
-
Test of isValidNumber method, of class org.owasp.esapi.Validator. -

-

-
-
-
-
- -

-testIsValidInteger

-
-public void testIsValidInteger()
-
-
-
-
-
-
- -

-testGetValidDate

-
-public void testGetValidDate()
-                      throws java.lang.Exception
-
-
Test of getValidDate method, of class org.owasp.esapi.Validator. -

-

- -
Throws: -
java.lang.Exception
-
-
-
- -

-testIsValidFileName

-
-public void testIsValidFileName()
-
-
Test of isValidFileName method, of class org.owasp.esapi.Validator. -

-

-
-
-
-
- -

-testIsValidDirectoryPath

-
-public void testIsValidDirectoryPath()
-
-
Test of isValidDirectoryPath method, of class org.owasp.esapi.Validator. -

-

-
-
-
-
- -

-testIsValidPrintable

-
-public void testIsValidPrintable()
-
-
-
-
-
-
- -

-testIsValidFileContent

-
-public void testIsValidFileContent()
-
-
Test of isValidFileContent method, of class org.owasp.esapi.Validator. -

-

-
-
-
-
- -

-testIsValidFileUpload

-
-public void testIsValidFileUpload()
-
-
Test of isValidFileUpload method, of class org.owasp.esapi.Validator. -

-

-
-
-
-
- -

-testIsValidParameterSet

-
-public void testIsValidParameterSet()
-
-
Test of isValidParameterSet method, of class org.owasp.esapi.Validator. -

-

-
-
-
-
- -

-testSafeReadLine

-
-public void testSafeReadLine()
-
-
Test safe read line. -

-

-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/AccessControllerTest.html b/javadoc/org/owasp/esapi/reference/class-use/AccessControllerTest.html deleted file mode 100644 index d2f775357..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/AccessControllerTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.AccessControllerTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.AccessControllerTest

-
-No usage of org.owasp.esapi.reference.AccessControllerTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/AccessReferenceMapTest.html b/javadoc/org/owasp/esapi/reference/class-use/AccessReferenceMapTest.html deleted file mode 100644 index 43526285e..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/AccessReferenceMapTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.AccessReferenceMapTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.AccessReferenceMapTest

-
-No usage of org.owasp.esapi.reference.AccessReferenceMapTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/AuthenticatorTest.html b/javadoc/org/owasp/esapi/reference/class-use/AuthenticatorTest.html deleted file mode 100644 index 7613628a8..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/AuthenticatorTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.AuthenticatorTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.AuthenticatorTest

-
-No usage of org.owasp.esapi.reference.AuthenticatorTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/DefaultEncoder.html b/javadoc/org/owasp/esapi/reference/class-use/DefaultEncoder.html deleted file mode 100644 index 27428afc3..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/DefaultEncoder.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.DefaultEncoder - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.DefaultEncoder

-
-No usage of org.owasp.esapi.reference.DefaultEncoder -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/DefaultEncryptedProperties.html b/javadoc/org/owasp/esapi/reference/class-use/DefaultEncryptedProperties.html deleted file mode 100644 index b450a53fb..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/DefaultEncryptedProperties.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.DefaultEncryptedProperties - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.DefaultEncryptedProperties

-
-No usage of org.owasp.esapi.reference.DefaultEncryptedProperties -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/DefaultExecutor.html b/javadoc/org/owasp/esapi/reference/class-use/DefaultExecutor.html deleted file mode 100644 index cc42e8c79..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/DefaultExecutor.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.DefaultExecutor - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.DefaultExecutor

-
-No usage of org.owasp.esapi.reference.DefaultExecutor -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/DefaultHTTPUtilities.html b/javadoc/org/owasp/esapi/reference/class-use/DefaultHTTPUtilities.html deleted file mode 100644 index b34e7f83a..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/DefaultHTTPUtilities.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.DefaultHTTPUtilities - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.DefaultHTTPUtilities

-
-No usage of org.owasp.esapi.reference.DefaultHTTPUtilities -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/DefaultIntrusionDetector.html b/javadoc/org/owasp/esapi/reference/class-use/DefaultIntrusionDetector.html deleted file mode 100644 index 0db44f654..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/DefaultIntrusionDetector.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.DefaultIntrusionDetector - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.DefaultIntrusionDetector

-
-No usage of org.owasp.esapi.reference.DefaultIntrusionDetector -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/DefaultRandomizer.html b/javadoc/org/owasp/esapi/reference/class-use/DefaultRandomizer.html deleted file mode 100644 index 8324bde54..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/DefaultRandomizer.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.DefaultRandomizer - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.DefaultRandomizer

-
-No usage of org.owasp.esapi.reference.DefaultRandomizer -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/DefaultSafeFile.html b/javadoc/org/owasp/esapi/reference/class-use/DefaultSafeFile.html deleted file mode 100644 index 4b57b4106..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/DefaultSafeFile.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.DefaultSafeFile - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.DefaultSafeFile

-
-No usage of org.owasp.esapi.reference.DefaultSafeFile -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/DefaultSecurityConfiguration.html b/javadoc/org/owasp/esapi/reference/class-use/DefaultSecurityConfiguration.html deleted file mode 100644 index 74a56bfa4..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/DefaultSecurityConfiguration.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.DefaultSecurityConfiguration - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.DefaultSecurityConfiguration

-
-No usage of org.owasp.esapi.reference.DefaultSecurityConfiguration -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/DefaultUser.html b/javadoc/org/owasp/esapi/reference/class-use/DefaultUser.html deleted file mode 100644 index 7500b1e65..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/DefaultUser.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.DefaultUser - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.DefaultUser

-
-No usage of org.owasp.esapi.reference.DefaultUser -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/DefaultValidator.html b/javadoc/org/owasp/esapi/reference/class-use/DefaultValidator.html deleted file mode 100644 index badd7f65d..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/DefaultValidator.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.DefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.DefaultValidator

-
-No usage of org.owasp.esapi.reference.DefaultValidator -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/EncoderTest.html b/javadoc/org/owasp/esapi/reference/class-use/EncoderTest.html deleted file mode 100644 index af038455a..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/EncoderTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.EncoderTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.EncoderTest

-
-No usage of org.owasp.esapi.reference.EncoderTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/EncryptedPropertiesTest.html b/javadoc/org/owasp/esapi/reference/class-use/EncryptedPropertiesTest.html deleted file mode 100644 index 70b106cb3..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/EncryptedPropertiesTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.EncryptedPropertiesTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.EncryptedPropertiesTest

-
-No usage of org.owasp.esapi.reference.EncryptedPropertiesTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/EncryptorTest.html b/javadoc/org/owasp/esapi/reference/class-use/EncryptorTest.html deleted file mode 100644 index 4d49cc6e7..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/EncryptorTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.EncryptorTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.EncryptorTest

-
-No usage of org.owasp.esapi.reference.EncryptorTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/ExecutorTest.html b/javadoc/org/owasp/esapi/reference/class-use/ExecutorTest.html deleted file mode 100644 index 92f4b6a0f..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/ExecutorTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.ExecutorTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.ExecutorTest

-
-No usage of org.owasp.esapi.reference.ExecutorTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/FileBasedAccessController.html b/javadoc/org/owasp/esapi/reference/class-use/FileBasedAccessController.html deleted file mode 100644 index b77c80979..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/FileBasedAccessController.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.FileBasedAccessController - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.FileBasedAccessController

-
-No usage of org.owasp.esapi.reference.FileBasedAccessController -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/FileBasedAuthenticator.html b/javadoc/org/owasp/esapi/reference/class-use/FileBasedAuthenticator.html deleted file mode 100644 index f7d267e6d..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/FileBasedAuthenticator.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.FileBasedAuthenticator - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.FileBasedAuthenticator

-
-No usage of org.owasp.esapi.reference.FileBasedAuthenticator -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/HTTPUtilitiesTest.html b/javadoc/org/owasp/esapi/reference/class-use/HTTPUtilitiesTest.html deleted file mode 100644 index 522cf2f6f..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/HTTPUtilitiesTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.HTTPUtilitiesTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.HTTPUtilitiesTest

-
-No usage of org.owasp.esapi.reference.HTTPUtilitiesTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/IntegerAccessReferenceMap.html b/javadoc/org/owasp/esapi/reference/class-use/IntegerAccessReferenceMap.html deleted file mode 100644 index 25bd88534..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/IntegerAccessReferenceMap.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.IntegerAccessReferenceMap - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.IntegerAccessReferenceMap

-
-No usage of org.owasp.esapi.reference.IntegerAccessReferenceMap -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/IntegerAccessReferenceMapTest.html b/javadoc/org/owasp/esapi/reference/class-use/IntegerAccessReferenceMapTest.html deleted file mode 100644 index acb7aedb1..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/IntegerAccessReferenceMapTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.IntegerAccessReferenceMapTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.IntegerAccessReferenceMapTest

-
-No usage of org.owasp.esapi.reference.IntegerAccessReferenceMapTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/IntrusionDetectorTest.html b/javadoc/org/owasp/esapi/reference/class-use/IntrusionDetectorTest.html deleted file mode 100644 index 50f267679..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/IntrusionDetectorTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.IntrusionDetectorTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.IntrusionDetectorTest

-
-No usage of org.owasp.esapi.reference.IntrusionDetectorTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/JSEEncryptor.html b/javadoc/org/owasp/esapi/reference/class-use/JSEEncryptor.html deleted file mode 100644 index 1fd9a8b47..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/JSEEncryptor.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.JSEEncryptor - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.JSEEncryptor

-
-No usage of org.owasp.esapi.reference.JSEEncryptor -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/JavaEncryptor.html b/javadoc/org/owasp/esapi/reference/class-use/JavaEncryptor.html deleted file mode 100644 index 38a94ad31..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/JavaEncryptor.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.JavaEncryptor - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.JavaEncryptor

-
-No usage of org.owasp.esapi.reference.JavaEncryptor -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/JavaLogFactory.html b/javadoc/org/owasp/esapi/reference/class-use/JavaLogFactory.html deleted file mode 100644 index bc4790919..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/JavaLogFactory.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.JavaLogFactory - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.JavaLogFactory

-
-No usage of org.owasp.esapi.reference.JavaLogFactory -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/LoggerTest.html b/javadoc/org/owasp/esapi/reference/class-use/LoggerTest.html deleted file mode 100644 index ef45f8831..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/LoggerTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.LoggerTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.LoggerTest

-
-No usage of org.owasp.esapi.reference.LoggerTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/RandomAccessReferenceMap.html b/javadoc/org/owasp/esapi/reference/class-use/RandomAccessReferenceMap.html deleted file mode 100644 index 04ef3984b..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/RandomAccessReferenceMap.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.RandomAccessReferenceMap - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.RandomAccessReferenceMap

-
-No usage of org.owasp.esapi.reference.RandomAccessReferenceMap -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/RandomizerTest.html b/javadoc/org/owasp/esapi/reference/class-use/RandomizerTest.html deleted file mode 100644 index 9328ebcac..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/RandomizerTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.RandomizerTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.RandomizerTest

-
-No usage of org.owasp.esapi.reference.RandomizerTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/SafeFileTest.html b/javadoc/org/owasp/esapi/reference/class-use/SafeFileTest.html deleted file mode 100644 index 57acaf38a..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/SafeFileTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.SafeFileTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.SafeFileTest

-
-No usage of org.owasp.esapi.reference.SafeFileTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/UserTest.html b/javadoc/org/owasp/esapi/reference/class-use/UserTest.html deleted file mode 100644 index d8c171ed6..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/UserTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.UserTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.UserTest

-
-No usage of org.owasp.esapi.reference.UserTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/class-use/ValidatorTest.html b/javadoc/org/owasp/esapi/reference/class-use/ValidatorTest.html deleted file mode 100644 index 5e7f99906..000000000 --- a/javadoc/org/owasp/esapi/reference/class-use/ValidatorTest.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.reference.ValidatorTest - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.reference.ValidatorTest

-
-No usage of org.owasp.esapi.reference.ValidatorTest -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/package-frame.html b/javadoc/org/owasp/esapi/reference/package-frame.html deleted file mode 100644 index c83a6697a..000000000 --- a/javadoc/org/owasp/esapi/reference/package-frame.html +++ /dev/null @@ -1,90 +0,0 @@ - - - - - - -org.owasp.esapi.reference - - - - - - - - - - - -org.owasp.esapi.reference - - - - -
-Classes  - -
-AccessControllerTest -
-AccessReferenceMapTest -
-AuthenticatorTest -
-DefaultEncoder -
-DefaultEncryptedProperties -
-DefaultExecutor -
-DefaultHTTPUtilities -
-DefaultIntrusionDetector -
-DefaultRandomizer -
-DefaultSecurityConfiguration -
-DefaultUser -
-DefaultValidator -
-EncoderTest -
-EncryptedPropertiesTest -
-EncryptorTest -
-ExecutorTest -
-FileBasedAccessController -
-FileBasedAuthenticator -
-HTTPUtilitiesTest -
-IntegerAccessReferenceMap -
-IntegerAccessReferenceMapTest -
-IntrusionDetectorTest -
-JavaEncryptor -
-JavaLogFactory -
-LoggerTest -
-RandomAccessReferenceMap -
-RandomizerTest -
-SafeFileTest -
-UserTest -
-ValidatorTest
- - - - diff --git a/javadoc/org/owasp/esapi/reference/package-summary.html b/javadoc/org/owasp/esapi/reference/package-summary.html deleted file mode 100644 index 47046d303..000000000 --- a/javadoc/org/owasp/esapi/reference/package-summary.html +++ /dev/null @@ -1,284 +0,0 @@ - - - - - - -org.owasp.esapi.reference - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-

-Package org.owasp.esapi.reference -

-This package contains reference implementations of the ESAPI interfaces. -

-See: -
-          Description -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Class Summary
AccessControllerTestThe Class AccessControllerTest.
AccessReferenceMapTestThe Class AccessReferenceMapTest.
AuthenticatorTestThe Class AuthenticatorTest.
DefaultEncoderReference implementation of the Encoder interface.
DefaultEncryptedPropertiesReference implementation of the EncryptedProperties interface.
DefaultExecutorReference implementation of the Executor interface.
DefaultHTTPUtilitiesReference implementation of the HTTPUtilities interface.
DefaultIntrusionDetectorReference implementation of the IntrusionDetector interface.
DefaultRandomizerReference implementation of the Randomizer interface.
DefaultSecurityConfigurationThe SecurityConfiguration manages all the settings used by the ESAPI in a single place.
DefaultUserReference implementation of the User interface.
DefaultValidatorReference implementation of the Validator interface.
EncoderTestThe Class EncoderTest.
EncryptedPropertiesTestThe Class EncryptedPropertiesTest.
EncryptorTestThe Class EncryptorTest.
ExecutorTestThe Class ExecutorTest.
FileBasedAccessControllerReference implementation of the AccessController interface.
FileBasedAuthenticatorReference implementation of the Authenticator interface.
HTTPUtilitiesTestThe Class HTTPUtilitiesTest.
IntegerAccessReferenceMapReference implementation of the AccessReferenceMap interface.
IntegerAccessReferenceMapTestThe Class AccessReferenceMapTest.
IntrusionDetectorTestThe Class IntrusionDetectorTest.
JavaEncryptorReference implementation of the Encryptor interface.
JavaLogFactoryReference implementation of the LogFactory and Logger interfaces.
LoggerTestThe Class LoggerTest.
RandomAccessReferenceMapReference implementation of the AccessReferenceMap interface.
RandomizerTestThe Class RandomizerTest.
SafeFileTestThe Class ExecutorTest.
UserTestThe Class UserTest.
ValidatorTestThe Class ValidatorTest.
-  - -

-

-Package org.owasp.esapi.reference Description -

- -

-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. -

- -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/package-tree.html b/javadoc/org/owasp/esapi/reference/package-tree.html deleted file mode 100644 index 6f5f5cf5e..000000000 --- a/javadoc/org/owasp/esapi/reference/package-tree.html +++ /dev/null @@ -1,165 +0,0 @@ - - - - - - -org.owasp.esapi.reference Class Hierarchy - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Hierarchy For Package org.owasp.esapi.reference -

-
-
-
Package Hierarchies:
All Packages
-
-

-Class Hierarchy -

- -
- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/reference/package-use.html b/javadoc/org/owasp/esapi/reference/package-use.html deleted file mode 100644 index e2a621f73..000000000 --- a/javadoc/org/owasp/esapi/reference/package-use.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Package org.owasp.esapi.reference - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Package
org.owasp.esapi.reference

-
-No usage of org.owasp.esapi.reference -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/tags/EncodeForHTMLAttributeTag.html b/javadoc/org/owasp/esapi/tags/EncodeForHTMLAttributeTag.html deleted file mode 100644 index 193d8f987..000000000 --- a/javadoc/org/owasp/esapi/tags/EncodeForHTMLAttributeTag.html +++ /dev/null @@ -1,380 +0,0 @@ - - - - - - -EncodeForHTMLAttributeTag - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.tags -
-Class EncodeForHTMLAttributeTag

-
-java.lang.Object
-  extended byjavax.servlet.jsp.tagext.TagSupport
-      extended byjavax.servlet.jsp.tagext.BodyTagSupport
-          extended byorg.owasp.esapi.tags.EncodeForHTMLAttributeTag
-
-
-
All Implemented Interfaces:
javax.servlet.jsp.tagext.BodyTag, javax.servlet.jsp.tagext.IterationTag, javax.servlet.jsp.tagext.JspTag, java.io.Serializable, javax.servlet.jsp.tagext.Tag
-
-
-
-
public class EncodeForHTMLAttributeTag
extends javax.servlet.jsp.tagext.BodyTagSupport
- -

-

-
See Also:
Serialized Form
-
- -

- - - - - - - - - - -
-Field Summary
- - - - - - - -
Fields inherited from interface javax.servlet.jsp.tagext.BodyTag
EVAL_BODY_BUFFERED, EVAL_BODY_TAG
- - - - - - - -
Fields inherited from interface javax.servlet.jsp.tagext.IterationTag
EVAL_BODY_AGAIN
- - - - - - - -
Fields inherited from interface javax.servlet.jsp.tagext.Tag
EVAL_BODY_INCLUDE, EVAL_PAGE, SKIP_BODY, SKIP_PAGE
-  - - - - - - - - - - -
-Constructor Summary
EncodeForHTMLAttributeTag() - -
-           
-  - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- intdoAfterBody() - -
-           
- intdoStartTag() - -
-           
- java.lang.StringgetName() - -
-           
- voidsetName(java.lang.String name) - -
-           
- - - - - - - -
Methods inherited from class javax.servlet.jsp.tagext.BodyTagSupport
doEndTag, doInitBody, getBodyContent, getPreviousOut, release, setBodyContent
- - - - - - - -
Methods inherited from class javax.servlet.jsp.tagext.TagSupport
findAncestorWithClass, getId, getParent, getValue, getValues, removeValue, setId, setPageContext, setParent, setValue
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
- - - - - - - -
Methods inherited from interface javax.servlet.jsp.tagext.Tag
getParent, setPageContext, setParent
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-EncodeForHTMLAttributeTag

-
-public EncodeForHTMLAttributeTag()
-
-
- - - - - - - - -
-Method Detail
- -

-doStartTag

-
-public int doStartTag()
-
-
-
-
-
-
- -

-doAfterBody

-
-public int doAfterBody()
-                throws javax.servlet.jsp.JspTagException
-
-
- -
Throws: -
javax.servlet.jsp.JspTagException
-
-
-
- -

-getName

-
-public java.lang.String getName()
-
-
-
-
-
-
- -

-setName

-
-public void setName(java.lang.String name)
-
-
-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/tags/EncodeForHTMLJavaScriptTag.html b/javadoc/org/owasp/esapi/tags/EncodeForHTMLJavaScriptTag.html deleted file mode 100644 index 532b854a4..000000000 --- a/javadoc/org/owasp/esapi/tags/EncodeForHTMLJavaScriptTag.html +++ /dev/null @@ -1,380 +0,0 @@ - - - - - - -EncodeForHTMLJavaScriptTag - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.tags -
-Class EncodeForHTMLJavaScriptTag

-
-java.lang.Object
-  extended byjavax.servlet.jsp.tagext.TagSupport
-      extended byjavax.servlet.jsp.tagext.BodyTagSupport
-          extended byorg.owasp.esapi.tags.EncodeForHTMLJavaScriptTag
-
-
-
All Implemented Interfaces:
javax.servlet.jsp.tagext.BodyTag, javax.servlet.jsp.tagext.IterationTag, javax.servlet.jsp.tagext.JspTag, java.io.Serializable, javax.servlet.jsp.tagext.Tag
-
-
-
-
public class EncodeForHTMLJavaScriptTag
extends javax.servlet.jsp.tagext.BodyTagSupport
- -

-

-
See Also:
Serialized Form
-
- -

- - - - - - - - - - -
-Field Summary
- - - - - - - -
Fields inherited from interface javax.servlet.jsp.tagext.BodyTag
EVAL_BODY_BUFFERED, EVAL_BODY_TAG
- - - - - - - -
Fields inherited from interface javax.servlet.jsp.tagext.IterationTag
EVAL_BODY_AGAIN
- - - - - - - -
Fields inherited from interface javax.servlet.jsp.tagext.Tag
EVAL_BODY_INCLUDE, EVAL_PAGE, SKIP_BODY, SKIP_PAGE
-  - - - - - - - - - - -
-Constructor Summary
EncodeForHTMLJavaScriptTag() - -
-           
-  - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- intdoAfterBody() - -
-           
- intdoStartTag() - -
-           
- java.lang.StringgetName() - -
-           
- voidsetName(java.lang.String name) - -
-           
- - - - - - - -
Methods inherited from class javax.servlet.jsp.tagext.BodyTagSupport
doEndTag, doInitBody, getBodyContent, getPreviousOut, release, setBodyContent
- - - - - - - -
Methods inherited from class javax.servlet.jsp.tagext.TagSupport
findAncestorWithClass, getId, getParent, getValue, getValues, removeValue, setId, setPageContext, setParent, setValue
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
- - - - - - - -
Methods inherited from interface javax.servlet.jsp.tagext.Tag
getParent, setPageContext, setParent
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-EncodeForHTMLJavaScriptTag

-
-public EncodeForHTMLJavaScriptTag()
-
-
- - - - - - - - -
-Method Detail
- -

-doStartTag

-
-public int doStartTag()
-
-
-
-
-
-
- -

-doAfterBody

-
-public int doAfterBody()
-                throws javax.servlet.jsp.JspTagException
-
-
- -
Throws: -
javax.servlet.jsp.JspTagException
-
-
-
- -

-getName

-
-public java.lang.String getName()
-
-
-
-
-
-
- -

-setName

-
-public void setName(java.lang.String name)
-
-
-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/tags/EncodeForHTMLTag.html b/javadoc/org/owasp/esapi/tags/EncodeForHTMLTag.html deleted file mode 100644 index c6526d460..000000000 --- a/javadoc/org/owasp/esapi/tags/EncodeForHTMLTag.html +++ /dev/null @@ -1,380 +0,0 @@ - - - - - - -EncodeForHTMLTag - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.tags -
-Class EncodeForHTMLTag

-
-java.lang.Object
-  extended byjavax.servlet.jsp.tagext.TagSupport
-      extended byjavax.servlet.jsp.tagext.BodyTagSupport
-          extended byorg.owasp.esapi.tags.EncodeForHTMLTag
-
-
-
All Implemented Interfaces:
javax.servlet.jsp.tagext.BodyTag, javax.servlet.jsp.tagext.IterationTag, javax.servlet.jsp.tagext.JspTag, java.io.Serializable, javax.servlet.jsp.tagext.Tag
-
-
-
-
public class EncodeForHTMLTag
extends javax.servlet.jsp.tagext.BodyTagSupport
- -

-

-
See Also:
Serialized Form
-
- -

- - - - - - - - - - -
-Field Summary
- - - - - - - -
Fields inherited from interface javax.servlet.jsp.tagext.BodyTag
EVAL_BODY_BUFFERED, EVAL_BODY_TAG
- - - - - - - -
Fields inherited from interface javax.servlet.jsp.tagext.IterationTag
EVAL_BODY_AGAIN
- - - - - - - -
Fields inherited from interface javax.servlet.jsp.tagext.Tag
EVAL_BODY_INCLUDE, EVAL_PAGE, SKIP_BODY, SKIP_PAGE
-  - - - - - - - - - - -
-Constructor Summary
EncodeForHTMLTag() - -
-           
-  - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- intdoAfterBody() - -
-           
- intdoStartTag() - -
-           
- java.lang.StringgetName() - -
-           
- voidsetName(java.lang.String name) - -
-           
- - - - - - - -
Methods inherited from class javax.servlet.jsp.tagext.BodyTagSupport
doEndTag, doInitBody, getBodyContent, getPreviousOut, release, setBodyContent
- - - - - - - -
Methods inherited from class javax.servlet.jsp.tagext.TagSupport
findAncestorWithClass, getId, getParent, getValue, getValues, removeValue, setId, setPageContext, setParent, setValue
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
- - - - - - - -
Methods inherited from interface javax.servlet.jsp.tagext.Tag
getParent, setPageContext, setParent
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-EncodeForHTMLTag

-
-public EncodeForHTMLTag()
-
-
- - - - - - - - -
-Method Detail
- -

-doStartTag

-
-public int doStartTag()
-
-
-
-
-
-
- -

-doAfterBody

-
-public int doAfterBody()
-                throws javax.servlet.jsp.JspTagException
-
-
- -
Throws: -
javax.servlet.jsp.JspTagException
-
-
-
- -

-getName

-
-public java.lang.String getName()
-
-
-
-
-
-
- -

-setName

-
-public void setName(java.lang.String name)
-
-
-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/tags/EncodeForVBScriptTag.html b/javadoc/org/owasp/esapi/tags/EncodeForVBScriptTag.html deleted file mode 100644 index 8caca48ac..000000000 --- a/javadoc/org/owasp/esapi/tags/EncodeForVBScriptTag.html +++ /dev/null @@ -1,399 +0,0 @@ - - - - - - -EncodeForVBScriptTag - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.tags -
-Class EncodeForVBScriptTag

-
-java.lang.Object
-  extended byjavax.servlet.jsp.tagext.TagSupport
-      extended byjavax.servlet.jsp.tagext.BodyTagSupport
-          extended byorg.owasp.esapi.tags.EncodeForVBScriptTag
-
-
-
All Implemented Interfaces:
javax.servlet.jsp.tagext.BodyTag, javax.servlet.jsp.tagext.IterationTag, javax.servlet.jsp.tagext.JspTag, java.io.Serializable, javax.servlet.jsp.tagext.Tag
-
-
-
-
public class EncodeForVBScriptTag
extends javax.servlet.jsp.tagext.BodyTagSupport
- -

-

-
See Also:
Serialized Form
-
- -

- - - - - - - - - - -
-Field Summary
- - - - - - - -
Fields inherited from interface javax.servlet.jsp.tagext.BodyTag
EVAL_BODY_BUFFERED, EVAL_BODY_TAG
- - - - - - - -
Fields inherited from interface javax.servlet.jsp.tagext.IterationTag
EVAL_BODY_AGAIN
- - - - - - - -
Fields inherited from interface javax.servlet.jsp.tagext.Tag
EVAL_BODY_INCLUDE, EVAL_PAGE, SKIP_BODY, SKIP_PAGE
-  - - - - - - - - - - -
-Constructor Summary
EncodeForVBScriptTag() - -
-           
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- intdoAfterBody() - -
-           
- intdoEndTag() - -
-           
- intdoStartTag() - -
-           
- java.lang.StringgetName() - -
-           
- voidsetName(java.lang.String name) - -
-           
- - - - - - - -
Methods inherited from class javax.servlet.jsp.tagext.BodyTagSupport
doInitBody, getBodyContent, getPreviousOut, release, setBodyContent
- - - - - - - -
Methods inherited from class javax.servlet.jsp.tagext.TagSupport
findAncestorWithClass, getId, getParent, getValue, getValues, removeValue, setId, setPageContext, setParent, setValue
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
- - - - - - - -
Methods inherited from interface javax.servlet.jsp.tagext.Tag
getParent, setPageContext, setParent
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-EncodeForVBScriptTag

-
-public EncodeForVBScriptTag()
-
-
- - - - - - - - -
-Method Detail
- -

-doStartTag

-
-public int doStartTag()
-
-
-
-
-
-
- -

-doEndTag

-
-public int doEndTag()
-
-
-
-
-
-
- -

-doAfterBody

-
-public int doAfterBody()
-                throws javax.servlet.jsp.JspTagException
-
-
- -
Throws: -
javax.servlet.jsp.JspTagException
-
-
-
- -

-getName

-
-public java.lang.String getName()
-
-
-
-
-
-
- -

-setName

-
-public void setName(java.lang.String name)
-
-
-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/tags/LogoutTag.html b/javadoc/org/owasp/esapi/tags/LogoutTag.html deleted file mode 100644 index 2b7bdb3f9..000000000 --- a/javadoc/org/owasp/esapi/tags/LogoutTag.html +++ /dev/null @@ -1,399 +0,0 @@ - - - - - - -LogoutTag - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- -

- -org.owasp.esapi.tags -
-Class LogoutTag

-
-java.lang.Object
-  extended byjavax.servlet.jsp.tagext.TagSupport
-      extended byjavax.servlet.jsp.tagext.BodyTagSupport
-          extended byorg.owasp.esapi.tags.LogoutTag
-
-
-
All Implemented Interfaces:
javax.servlet.jsp.tagext.BodyTag, javax.servlet.jsp.tagext.IterationTag, javax.servlet.jsp.tagext.JspTag, java.io.Serializable, javax.servlet.jsp.tagext.Tag
-
-
-
-
public class LogoutTag
extends javax.servlet.jsp.tagext.BodyTagSupport
- -

-

-
See Also:
Serialized Form
-
- -

- - - - - - - - - - -
-Field Summary
- - - - - - - -
Fields inherited from interface javax.servlet.jsp.tagext.BodyTag
EVAL_BODY_BUFFERED, EVAL_BODY_TAG
- - - - - - - -
Fields inherited from interface javax.servlet.jsp.tagext.IterationTag
EVAL_BODY_AGAIN
- - - - - - - -
Fields inherited from interface javax.servlet.jsp.tagext.Tag
EVAL_BODY_INCLUDE, EVAL_PAGE, SKIP_BODY, SKIP_PAGE
-  - - - - - - - - - - -
-Constructor Summary
LogoutTag() - -
-           
-  - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Method Summary
- intdoAfterBody() - -
-           
- intdoEndTag() - -
-           
- intdoStartTag() - -
-           
- java.lang.StringgetName() - -
-           
- voidsetName(java.lang.String name) - -
-           
- - - - - - - -
Methods inherited from class javax.servlet.jsp.tagext.BodyTagSupport
doInitBody, getBodyContent, getPreviousOut, release, setBodyContent
- - - - - - - -
Methods inherited from class javax.servlet.jsp.tagext.TagSupport
findAncestorWithClass, getId, getParent, getValue, getValues, removeValue, setId, setPageContext, setParent, setValue
- - - - - - - -
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
- - - - - - - -
Methods inherited from interface javax.servlet.jsp.tagext.Tag
getParent, setPageContext, setParent
-  -

- - - - - - - - - - - -
-Constructor Detail
- -

-LogoutTag

-
-public LogoutTag()
-
-
- - - - - - - - -
-Method Detail
- -

-doStartTag

-
-public int doStartTag()
-
-
-
-
-
-
- -

-doEndTag

-
-public int doEndTag()
-
-
-
-
-
-
- -

-doAfterBody

-
-public int doAfterBody()
-                throws javax.servlet.jsp.JspTagException
-
-
- -
Throws: -
javax.servlet.jsp.JspTagException
-
-
-
- -

-getName

-
-public java.lang.String getName()
-
-
-
-
-
-
- -

-setName

-
-public void setName(java.lang.String name)
-
-
-
-
-
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/tags/class-use/EncodeForHTMLAttributeTag.html b/javadoc/org/owasp/esapi/tags/class-use/EncodeForHTMLAttributeTag.html deleted file mode 100644 index 6000869f9..000000000 --- a/javadoc/org/owasp/esapi/tags/class-use/EncodeForHTMLAttributeTag.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.tags.EncodeForHTMLAttributeTag - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.tags.EncodeForHTMLAttributeTag

-
-No usage of org.owasp.esapi.tags.EncodeForHTMLAttributeTag -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/tags/class-use/EncodeForHTMLJavaScriptTag.html b/javadoc/org/owasp/esapi/tags/class-use/EncodeForHTMLJavaScriptTag.html deleted file mode 100644 index d1b5a2d35..000000000 --- a/javadoc/org/owasp/esapi/tags/class-use/EncodeForHTMLJavaScriptTag.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.tags.EncodeForHTMLJavaScriptTag - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.tags.EncodeForHTMLJavaScriptTag

-
-No usage of org.owasp.esapi.tags.EncodeForHTMLJavaScriptTag -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/tags/class-use/EncodeForHTMLTag.html b/javadoc/org/owasp/esapi/tags/class-use/EncodeForHTMLTag.html deleted file mode 100644 index 4a6ba24d2..000000000 --- a/javadoc/org/owasp/esapi/tags/class-use/EncodeForHTMLTag.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.tags.EncodeForHTMLTag - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.tags.EncodeForHTMLTag

-
-No usage of org.owasp.esapi.tags.EncodeForHTMLTag -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/tags/class-use/EncodeForVBScriptTag.html b/javadoc/org/owasp/esapi/tags/class-use/EncodeForVBScriptTag.html deleted file mode 100644 index b9b6674f2..000000000 --- a/javadoc/org/owasp/esapi/tags/class-use/EncodeForVBScriptTag.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.tags.EncodeForVBScriptTag - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.tags.EncodeForVBScriptTag

-
-No usage of org.owasp.esapi.tags.EncodeForVBScriptTag -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/tags/class-use/LogoutTag.html b/javadoc/org/owasp/esapi/tags/class-use/LogoutTag.html deleted file mode 100644 index 7e4485f10..000000000 --- a/javadoc/org/owasp/esapi/tags/class-use/LogoutTag.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Class org.owasp.esapi.tags.LogoutTag - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Class
org.owasp.esapi.tags.LogoutTag

-
-No usage of org.owasp.esapi.tags.LogoutTag -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/tags/package-frame.html b/javadoc/org/owasp/esapi/tags/package-frame.html deleted file mode 100644 index 157c156cd..000000000 --- a/javadoc/org/owasp/esapi/tags/package-frame.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - -org.owasp.esapi.tags - - - - - - - - - - - -org.owasp.esapi.tags - - - - -
-Classes  - -
-EncodeForHTMLAttributeTag -
-EncodeForHTMLJavaScriptTag -
-EncodeForHTMLTag -
-EncodeForVBScriptTag
- - - - diff --git a/javadoc/org/owasp/esapi/tags/package-summary.html b/javadoc/org/owasp/esapi/tags/package-summary.html deleted file mode 100644 index bc86ad8c3..000000000 --- a/javadoc/org/owasp/esapi/tags/package-summary.html +++ /dev/null @@ -1,160 +0,0 @@ - - - - - - -org.owasp.esapi.tags - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-

-Package org.owasp.esapi.tags -

- - - - - - - - - - - - - - - - - - - - - -
-Class Summary
EncodeForHTMLAttributeTag 
EncodeForHTMLJavaScriptTag 
EncodeForHTMLTag 
EncodeForVBScriptTag 
-  - -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/tags/package-tree.html b/javadoc/org/owasp/esapi/tags/package-tree.html deleted file mode 100644 index 47dd900e7..000000000 --- a/javadoc/org/owasp/esapi/tags/package-tree.html +++ /dev/null @@ -1,151 +0,0 @@ - - - - - - -org.owasp.esapi.tags Class Hierarchy - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Hierarchy For Package org.owasp.esapi.tags -

-
-
-
Package Hierarchies:
All Packages
-
-

-Class Hierarchy -

-
    -
  • class java.lang.Object -
-
- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/org/owasp/esapi/tags/package-use.html b/javadoc/org/owasp/esapi/tags/package-use.html deleted file mode 100644 index e3af48529..000000000 --- a/javadoc/org/owasp/esapi/tags/package-use.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - -Uses of Package org.owasp.esapi.tags - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Uses of Package
org.owasp.esapi.tags

-
-No usage of org.owasp.esapi.tags -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/overview-frame.html b/javadoc/overview-frame.html deleted file mode 100644 index e971885a9..000000000 --- a/javadoc/overview-frame.html +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - -Overview - - - - - - - - - - - - - - - -
-
- - - - - -
All Classes -

- -Packages -
-org.owasp.esapi -
-org.owasp.esapi.codecs -
-org.owasp.esapi.errors -
-org.owasp.esapi.filters -
-org.owasp.esapi.http -
-org.owasp.esapi.reference -
-org.owasp.esapi.tags -
-

- -

-  - - diff --git a/javadoc/overview-summary.html b/javadoc/overview-summary.html deleted file mode 100644 index ac416163c..000000000 --- a/javadoc/overview-summary.html +++ /dev/null @@ -1,234 +0,0 @@ - - - - - - -Overview - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -


-
-

-OWASP Enterprise Security API (ESAPI) -

-
- -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. -

-See: -
-          Description -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Packages
org.owasp.esapiThe ESAPI interfaces and Exception classes model the most important security -functions to enterprise web applications.
org.owasp.esapi.codecs 
org.owasp.esapi.errorsA set of exception classes designed to model the error conditions that -frequently arise in enterprise web applications and web services.
org.owasp.esapi.filters 
org.owasp.esapi.httpA few simple mock classes to help test the ESAPI reference -implementation.
org.owasp.esapi.referenceThis package contains reference implementations of the ESAPI interfaces.
org.owasp.esapi.tags 
- -

-

-

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/overview-tree.html b/javadoc/overview-tree.html deleted file mode 100644 index 4f4e04d06..000000000 --- a/javadoc/overview-tree.html +++ /dev/null @@ -1,219 +0,0 @@ - - - - - - -Class Hierarchy - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Hierarchy For All Packages

-
-
-
Package Hierarchies:
org.owasp.esapi, org.owasp.esapi.codecs, org.owasp.esapi.errors, org.owasp.esapi.filters, org.owasp.esapi.http, org.owasp.esapi.reference, org.owasp.esapi.tags
-
-

-Class Hierarchy -

- -

-Interface Hierarchy -

- -
- - - - - - - - - - - - - - - -
- -
- - - -
- - - diff --git a/javadoc/package-list b/javadoc/package-list deleted file mode 100644 index fd558a0b1..000000000 --- a/javadoc/package-list +++ /dev/null @@ -1,7 +0,0 @@ -org.owasp.esapi -org.owasp.esapi.codecs -org.owasp.esapi.errors -org.owasp.esapi.filters -org.owasp.esapi.http -org.owasp.esapi.reference -org.owasp.esapi.tags diff --git a/javadoc/packages.html b/javadoc/packages.html deleted file mode 100644 index ce9dc3256..000000000 --- a/javadoc/packages.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - -
- -
- -
-
-The front page has been relocated.Please see: -
-          Frame version -
-          Non-frame version.
- - - diff --git a/javadoc/resources/inherit.gif b/javadoc/resources/inherit.gif deleted file mode 100644 index c814867a1..000000000 Binary files a/javadoc/resources/inherit.gif and /dev/null differ diff --git a/javadoc/serialized-form.html b/javadoc/serialized-form.html deleted file mode 100644 index 1ce56a828..000000000 --- a/javadoc/serialized-form.html +++ /dev/null @@ -1,866 +0,0 @@ - - - - - - -Serialized Form - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-

-Serialized Form

-
-
- - - - - -
-Package org.owasp.esapi.errors
- -

- - - - - -
-Class org.owasp.esapi.errors.AccessControlException extends EnterpriseSecurityException implements Serializable
- -

-serialVersionUID: 1l - -

- -

- - - - - -
-Class org.owasp.esapi.errors.AuthenticationAccountsException extends AuthenticationException implements Serializable
- -

-serialVersionUID: 1l - -

- -

- - - - - -
-Class org.owasp.esapi.errors.AuthenticationCredentialsException extends AuthenticationException implements Serializable
- -

-serialVersionUID: 1l - -

- -

- - - - - -
-Class org.owasp.esapi.errors.AuthenticationException extends EnterpriseSecurityException implements Serializable
- -

-serialVersionUID: 1l - -

- -

- - - - - -
-Class org.owasp.esapi.errors.AuthenticationHostException extends AuthenticationException implements Serializable
- -

-serialVersionUID: 1l - -

- -

- - - - - -
-Class org.owasp.esapi.errors.AuthenticationLoginException extends AuthenticationException implements Serializable
- -

-serialVersionUID: 1l - -

- -

- - - - - -
-Class org.owasp.esapi.errors.AvailabilityException extends EnterpriseSecurityException implements Serializable
- -

-serialVersionUID: 1l - -

- -

- - - - - -
-Class org.owasp.esapi.errors.CertificateException extends EnterpriseSecurityException implements Serializable
- -

-serialVersionUID: 1l - -

- -

- - - - - -
-Class org.owasp.esapi.errors.EncodingException extends EnterpriseSecurityException implements Serializable
- -

-serialVersionUID: 1l - -

- -

- - - - - -
-Class org.owasp.esapi.errors.EncryptionException extends EnterpriseSecurityException implements Serializable
- -

-serialVersionUID: 1l - -

- -

- - - - - -
-Class org.owasp.esapi.errors.EnterpriseSecurityException extends java.lang.Exception implements Serializable
- -

-serialVersionUID: 1l - -

- - - - - -
-Serialized Fields
- -

-logger

-
-Logger logger
-
-
The logger. -

-

-
-
-
- -

-logMessage

-
-java.lang.String logMessage
-
-
-
-
- -

- - - - - -
-Class org.owasp.esapi.errors.ExecutorException extends EnterpriseSecurityException implements Serializable
- -

-serialVersionUID: 1l - -

- -

- - - - - -
-Class org.owasp.esapi.errors.IntegrityException extends EnterpriseSecurityException implements Serializable
- -

-serialVersionUID: 1l - -

- -

- - - - - -
-Class org.owasp.esapi.errors.IntrusionException extends java.lang.RuntimeException implements Serializable
- -

-serialVersionUID: 1l - -

- - - - - -
-Serialized Fields
- -

-logger

-
-Logger logger
-
-
The logger. -

-

-
-
-
- -

-logMessage

-
-java.lang.String logMessage
-
-
-
-
- -

- - - - - -
-Class org.owasp.esapi.errors.ValidationAvailabilityException extends ValidationException implements Serializable
- -

-serialVersionUID: 1l - -

- -

- - - - - -
-Class org.owasp.esapi.errors.ValidationException extends EnterpriseSecurityException implements Serializable
- -

-serialVersionUID: 1l - -

- - - - - -
-Serialized Fields
- -

-context

-
-java.lang.String context
-
-
The UI reference that caused this ValidationException -

-

-
-
- -

- - - - - -
-Class org.owasp.esapi.errors.ValidationUploadException extends ValidationException implements Serializable
- -

-serialVersionUID: 1l - -

- -

-


- - - - - -
-Package org.owasp.esapi.reference
- -

- - - - - -
-Class org.owasp.esapi.reference.DefaultUser extends java.lang.Object implements Serializable
- -

-serialVersionUID: 1l - -

- - - - - -
-Serialized Fields
- -

-logger

-
-Logger logger
-
-
The logger. -

-

-
-
-
- -

-accountId

-
-long accountId
-
-
The account id. -

-

-
-
-
- -

-accountName

-
-java.lang.String accountName
-
-
The account name. -

-

-
-
-
- -

-screenName

-
-java.lang.String screenName
-
-
The screen name. -

-

-
-
-
- -

-csrfToken

-
-java.lang.String csrfToken
-
-
The csrf token. -

-

-
-
-
- -

-roles

-
-java.util.Set roles
-
-
The roles. -

-

-
-
-
- -

-locked

-
-boolean locked
-
-
The locked. -

-

-
-
-
- -

-loggedIn

-
-boolean loggedIn
-
-
The logged in. -

-

-
-
-
- -

-enabled

-
-boolean enabled
-
-
The enabled. -

-

-
-
-
- -

-lastHostAddress

-
-java.lang.String lastHostAddress
-
-
The last host address used. -

-

-
-
-
- -

-lastPasswordChangeTime

-
-java.util.Date lastPasswordChangeTime
-
-
The last password change time. -

-

-
-
-
- -

-lastLoginTime

-
-java.util.Date lastLoginTime
-
-
The last login time. -

-

-
-
-
- -

-lastFailedLoginTime

-
-java.util.Date lastFailedLoginTime
-
-
The last failed login time. -

-

-
-
-
- -

-expirationTime

-
-java.util.Date expirationTime
-
-
The expiration time. -

-

-
-
-
- -

-failedLoginCount

-
-int failedLoginCount
-
-
The failed login count. -

-

-
-
-
- -

-MAX_ROLE_LENGTH

-
-int MAX_ROLE_LENGTH
-
-
-
See Also:
Constant Field Values
-
- -

-


- - - - - -
-Package org.owasp.esapi
- -

- - - - - -
-Class org.owasp.esapi.SafeFile extends java.io.File implements Serializable
- -

-serialVersionUID: 1l - -

- - - - - -
-Serialized Fields
- -

-percents

-
-java.util.regex.Pattern percents
-
-
-
-
-
- -

-dirblacklist

-
-java.util.regex.Pattern dirblacklist
-
-
-
-
-
- -

-fileblacklist

-
-java.util.regex.Pattern fileblacklist
-
-
-
-
- -

-


- - - - - -
-Package org.owasp.esapi.tags
- -

- - - - - -
-Class org.owasp.esapi.tags.EncodeForHTMLAttributeTag extends javax.servlet.jsp.tagext.BodyTagSupport implements Serializable
- -

-serialVersionUID: 1l - -

- - - - - -
-Serialized Fields
- -

-name

-
-java.lang.String name
-
-
-
-
- -

- - - - - -
-Class org.owasp.esapi.tags.EncodeForHTMLJavaScriptTag extends javax.servlet.jsp.tagext.BodyTagSupport implements Serializable
- -

-serialVersionUID: 1l - -

- - - - - -
-Serialized Fields
- -

-name

-
-java.lang.String name
-
-
-
-
- -

- - - - - -
-Class org.owasp.esapi.tags.EncodeForHTMLTag extends javax.servlet.jsp.tagext.BodyTagSupport implements Serializable
- -

-serialVersionUID: 1l - -

- - - - - -
-Serialized Fields
- -

-name

-
-java.lang.String name
-
-
-
-
- -

- - - - - -
-Class org.owasp.esapi.tags.EncodeForVBScriptTag extends javax.servlet.jsp.tagext.BodyTagSupport implements Serializable
- -

-serialVersionUID: 1l - -

- - - - - -
-Serialized Fields
- -

-name

-
-java.lang.String name
-
-
-
-
- -

-


- - - - - - - - - - - - - - - -
- -
- - - -
- - - 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: + * + *

+ * try {
+ *     ESAPI.accessController().assertAuthorized("businessFunction", runtimeData);
+ *     // execute BUSINESS_FUNCTION
+ * } catch (AccessControlException ace) {
+ * ... 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. + * + *
+ * <% if ( ESAPI.accessController().isAuthorized( "businessFunction", runtimeData ) ) { %>
+ * <a href="/doAdminFunction">ADMIN</a>
+ * <% } else { %>
+ * <a href="/doNormalFunction">NORMAL</a>
+ * <% } %>
+ * 
+ * + * @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: + *
ESAPI.accessController().isAuthorizedForURL(request.getRequestURI().toString());
+ * + * 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: + *
ESAPI.accessController().assertAuthorizedForURL(request.getRequestURI().toString());
+ * + * 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: + *

    + *
  1. Check to see if the resource exists and if not, throw an AccessControlException
  2. + *
  3. Use available information to make an access control decision
  4. + *
      + *
    1. Ideally, this policy would be data driven
    2. + *
    3. You can use the current User, roles, data type, data name, time of day, etc.
    4. + *
    5. Access control decisions must deny by default
    6. + *
    + *
  5. If access is not permitted, throw an AccessControlException with details
  6. + *
+ * @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: + *

    + *
  1. Check to see if the function exists and if not, throw an AccessControlException
  2. + *
  3. Use available information to make an access control decision
  4. + *
      + *
    1. Ideally, this policy would be data driven
    2. + *
    3. You can use the current User, roles, data type, data name, time of day, etc.
    4. + *
    5. Access control decisions must deny by default
    6. + *
    + *
  5. If access is not permitted, throw an AccessControlException with details
  6. + *
+ * + * @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: + *

    + *
  1. Check to see if the resource exists and if not, throw an AccessControlException
  2. + *
  3. Use available information to make an access control decision
  4. + *
      + *
    1. Ideally, this policy would be data driven
    2. + *
    3. You can use the current User, roles, data type, data name, time of day, etc.
    4. + *
    5. Access control decisions must deny by default
    6. + *
    + *
  5. If access is not permitted, throw an AccessControlException with details
  6. + *
+ * + * @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: + *

    + *
  1. Check to see if the File exists and if not, throw an AccessControlException
  2. + *
  3. Use available information to make an access control decision
  4. + *
      + *
    1. Ideally, this policy would be data driven
    2. + *
    3. You can use the current User, roles, data type, data name, time of day, etc.
    4. + *
    5. Access control decisions must deny by default
    6. + *
    + *
  5. If access is not permitted, throw an AccessControlException with details
  6. + *
+ * + * @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: + *

    + *
  1. Check to see if the service exists and if not, throw an AccessControlException
  2. + *
  3. Use available information to make an access control decision
  4. + *
      + *
    1. Ideally, this policy would be data driven
    2. + *
    3. You can use the current User, roles, data type, data name, time of day, etc.
    4. + *
    5. Access control decisions must deny by default
    6. + *
    + *
  5. If access is not permitted, throw an AccessControlException with details
  6. + *
+ * + * @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: + *

+    * UserProfile profile = arm.getDirectReference( indirectRef );
+    * 
+ * + * Will throw a AccessControlException if the object stored in memory is not of type + * UserProfile. + * + * However, + *
+    * Object uncastObject = arm.getDirectReference( indirectRef );
+    * 
+ * + * 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. + *
+    * Object uncastProfile = arm.getDirectReference( indirectRef );
+    * if ( uncastProfile instanceof UserProfile ) {
+    *     UserProfile userProfile = (UserProfile) uncastProfile;
+    *     // ...
+    * } else {
+    *     EmployeeProfile employeeProfile = (EmployeeProfile) uncastProfile;
+    *     // ...
+    * }
+    * 
+ * + * @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. + *

+        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException {
+            try {
+                HttpServletRequest request = (HttpServletRequest) req;
+                HttpServletResponse response = (HttpServletResponse) resp;
+                ESAPI.httpUtilities().setCurrentHTTP(request, response);
+                ESAPI.authenticator().login();
+                chain.doFilter(request, response);
+            } catch (Exception e) {
+                logger.error( Logger.SECURITY_FAILURE, "Error in ESAPI security filter: " + e.getMessage(), e );
+            } finally {
+                // VERY IMPORTANT
+                // clear out ThreadLocal variables
+                ESAPI.clearCurrent();
+            }
+        }
+     * 
+ * 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. + *
  • + *
+ *

+ * @see OWASP Cross-Site Scripting Prevention Cheat Sheet + * @see org.owasp.esapi.Validator + * @see OWASP Proactive Controls: C4: Encode and Escape Data + * @see Properly encoding and escaping for the web + * @author Jeff Williams (jeff.williams .at. owasp.org) + * @since June 1, 2007 + */ +public interface Encoder { + + /** + * This method is equivalent to calling {@code Encoder.canonicalize(input, restrictMultiple, restrictMixed);}. + * + * The default values for {@code restrictMultiple} and {@code restrictMixed} come from {@code ESAPI.properties}. + *
+     * Encoder.AllowMultipleEncoding=false
+     * Encoder.AllowMixedEncoding=false
+     * 
+ * and the default codecs that are used for canonicalization are the list + * of codecs that comes from: + *
+     * Encoder.DefaultCodecList=HTMLEntityCodec,PercentCodec,JavaScriptCodec
+     * 
+ * (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 &lt;)
  • + *
  • 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... + *

+     *     String clean = ESAPI.encoder().canonicalize( request.getParameter("input"));
+     * 
+ * 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: + *
+     * Encoder.DefaultCodecList=WindowsCodec,MySQLCodec,PercentCodec
+     * 
+ * and then use: + *
+     *     Encoder encoder = ESAPI.encoder();
+     *     String clean = encoder.canonicalize( request.getParameter( "input" ));
+     * 
+ * 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. + *

+     *     String input = request.getParameter( "name" );
+     *     String name = ESAPI.validator().isValidInput( "test", input, "FirstName", 20, false);
+     * 
+ * 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. + *
+     *     ... setup custom encoder as above
+     *     Validator validator = new DefaultValidator( encoder );
+     *     String input = request.getParameter( "name" );
+     *     String name = validator.isValidInput( "test", input, "name", 20, false);
+     * 
+ * 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: + *
+     * Encoder.AllowMultipleEncoding=false
+     * Encoder.AllowMixedEncoding=false
+     * 
+ * 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. + *
+     *     // disabling strict mode to allow mixed encoding
+     *     String url = ESAPI.encoder().canonicalize( request.getParameter("url"), false, false);
+     * 
+ * 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 "&para;" in a URL like + * "https://foo.com/?bar=foo&parameter=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 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. + * + * @see Character Encoding in Entities + * + * @param input + * the text to encode for use as an XML attribute + * + * @return + * input encoded for use in an XML attribute + */ + String encodeForXMLAttribute(String input); + + /** + * Encode for use in a URL. This method performs URL encoding + * on the entire string. + * + * @see URL encoding + * + * @param input + * the text to encode for use in a URL + * + * @return input + * encoded for use in a URL + * + * @throws EncodingException + * if encoding fails + */ + String encodeForURL(String input) throws EncodingException; + + /** + * Encode data for use in JSON strings. This method performs String escaping + * on the entire string according to RFC 8259, Section 7. + * + * @see RFC 8259, + * The JavaScript Object Notation (JSON) Data Interchange Format, Section 7 + * + * @param input + * the text to escape for JSON string + * + * @return input + * escaped for use in JSON string + */ + String encodeForJSON(String input); + + /** + * Decode from URL. Implementations should first canonicalize and + * detect any double-encoding. If this check passes, then the data is decoded using URL + * decoding. + * + * @param input + * the text to decode from an encoded URL + * + * @return + * the decoded URL value + * + * @throws EncodingException + * if decoding fails + */ + String decodeFromURL(String input) throws EncodingException; + + /** + * Encode for Base64. + * + * @param input + * the text to encode for Base64 + * @param wrap + * the encoder will wrap lines every 64 characters of output + * + * @return input encoded for Base64 + */ + String encodeForBase64(byte[] input, boolean wrap); + + /** + * Decode data encoded with BASE-64 encoding. + * + * @param input + * the Base64 text to decode + * + * @return input decoded from Base64 + * + * @throws IOException + */ + byte[] decodeFromBase64(String input) throws IOException; + + /** + * Get a version of the input URI that will be safe to run regex and other validations against. + * It is not recommended to persist this value as it will transform user input. This method + * will not test to see if the URI is RFC-3986 compliant. + * + * @param dirtyUri + * the tainted URI + * @return The canonicalized URI + */ + String getCanonicalizedURI(URI dirtyUri); + + /** + * Decode data encoded for JSON strings. This method removes String escaping + * on the entire string according to RFC 8259, Section 7. + * + * @see RFC 8259, + * The JavaScript Object Notation (JSON) Data Interchange Format, Section 7 + * + * @param input + * the JSON string to decode + * + * @return input + * decoded from JSON string + */ + String decodeFromJSON(String input); +} diff --git a/src/main/java/org/owasp/esapi/EncoderConstants.java b/src/main/java/org/owasp/esapi/EncoderConstants.java new file mode 100644 index 000000000..ec2cbfac4 --- /dev/null +++ b/src/main/java/org/owasp/esapi/EncoderConstants.java @@ -0,0 +1,117 @@ +package org.owasp.esapi; + +import java.util.Set; + +import org.owasp.esapi.util.CollectionsUtil; + +/** + * Common character classes used for input validation, output encoding, verifying password strength + * CSRF token generation, generating salts, etc + * @author Neil Matatall (neil.matatall .at. gmail.com) + * @see User + */ +public class EncoderConstants { + /** + * !$*-.=?@_ + */ + public final static char[] CHAR_PASSWORD_SPECIALS = { '!', '$', '*', '-', '.', '=', '?', '@', '_' }; + public final static Set PASSWORD_SPECIALS; + static { + PASSWORD_SPECIALS = CollectionsUtil.arrayToSet(CHAR_PASSWORD_SPECIALS); + } + + /** + * a-b + */ + public final static char[] CHAR_LOWERS = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' }; + public final static Set LOWERS; + static { + LOWERS = CollectionsUtil.arrayToSet(CHAR_PASSWORD_SPECIALS); + } + + /** + * A-Z + */ + public final static char[] CHAR_UPPERS = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; + public final static Set UPPERS; + static { + UPPERS = CollectionsUtil.arrayToSet(CHAR_UPPERS); + } + /** + * 0-9 + */ + public final static char[] CHAR_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; + public final static Set DIGITS; + static { + DIGITS = CollectionsUtil.arrayToSet(CHAR_DIGITS); + } + + /** + * !$*+-.=?@^_|~ + */ + public final static char[] CHAR_SPECIALS = { '!', '$', '*', '+', '-', '.', '=', '?', '@', '^', '_', '|', '~' }; + public final static Set SPECIALS; + static { + SPECIALS = CollectionsUtil.arrayToSet(CHAR_SPECIALS); + } + + /** + * CHAR_LOWERS union CHAR_UPPERS + */ + public final static char[] CHAR_LETTERS = StringUtilities.union(CHAR_LOWERS, CHAR_UPPERS); + public final static Set LETTERS; + static { + LETTERS = CollectionsUtil.arrayToSet(CHAR_LETTERS); + } + + /** + * CHAR_LETTERS union CHAR_DIGITS + */ + public final static char[] CHAR_ALPHANUMERICS = StringUtilities.union(CHAR_LETTERS, CHAR_DIGITS); + public final static Set ALPHANUMERICS; + static { + ALPHANUMERICS = CollectionsUtil.arrayToSet(CHAR_ALPHANUMERICS); + } + + /** + * 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...) + */ + public final static char[] CHAR_PASSWORD_LOWERS = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' }; + public final static Set PASSWORD_LOWERS; + static { + PASSWORD_LOWERS = CollectionsUtil.arrayToSet(CHAR_ALPHANUMERICS); + } + + /** + * + */ + public final static char[] CHAR_PASSWORD_UPPERS = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; + public final static Set PASSWORD_UPPERS; + static { + PASSWORD_UPPERS = CollectionsUtil.arrayToSet(CHAR_PASSWORD_UPPERS); + } + + /** + * 2-9 + */ + public final static char[] CHAR_PASSWORD_DIGITS = { '2', '3', '4', '5', '6', '7', '8', '9' }; + public final static Set PASSWORD_DIGITS; + static { + PASSWORD_DIGITS = CollectionsUtil.arrayToSet(CHAR_PASSWORD_DIGITS); + } + + /** + * CHAR_PASSWORD_LOWERS union CHAR_PASSWORD_UPPERS + */ + public final static char[] CHAR_PASSWORD_LETTERS = StringUtilities.union( CHAR_PASSWORD_LOWERS, CHAR_PASSWORD_UPPERS ); + public final static Set PASSWORD_LETTERS; + static { + PASSWORD_LETTERS = CollectionsUtil.arrayToSet(CHAR_PASSWORD_LETTERS); + } + + private EncoderConstants() { + // prevent instantiation + } +} diff --git a/src/main/java/org/owasp/esapi/EncryptedProperties.java b/src/main/java/org/owasp/esapi/EncryptedProperties.java new file mode 100644 index 000000000..b1db53112 --- /dev/null +++ b/src/main/java/org/owasp/esapi/EncryptedProperties.java @@ -0,0 +1,112 @@ +/** + * 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.io.InputStream; +import java.io.OutputStream; +import java.util.Set; + +import org.owasp.esapi.errors.EncryptionException; + + +/** + * The {@code 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 {@link java.util.Properties} and overloading + * the {@code getProperty} and {@code setProperty} methods. In all cases, + * the master encryption key, as given by the {@code Encryptor.MasterKey} + * property in ESAPI.properties file. + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @since June 1, 2007 + */ +public interface EncryptedProperties { + + /** + * Gets the property value from the encrypted store, decrypts it, and + * returns the plaintext value to the caller. + * + * @param key + * the name of the property to get + * + * @return + * The decrypted property value. null if the key is not set. + * + * @throws EncryptionException + * if the property could not be decrypted + */ + String getProperty(String key) throws EncryptionException; + + /** + * Encrypts the plaintext property value and stores the ciphertext value + * in the encrypted store. + * + * @param key + * the name of the property to set + * @param value + * the value of the property to set + * + * @return + * the previously encrypted property value for the specified key, or + * {@code null} if it did not have one. + * + * @throws EncryptionException + * if the property could not be encrypted + */ + String setProperty(String key, String value) throws EncryptionException; + + /** + * Returns a {@code Set} view of properties. The {@code Set} is backed by a + * {@code java.util.Hashtable}, so changes to the {@code Hashtable} are + * reflected in the {@code Set}, and vice-versa. The {@code Set} supports element + * removal (which removes the corresponding entry from the {@code Hashtable}, + * but not element addition. + * + * @return + * a set view of the properties contained in this map. + */ + Set keySet(); + + /** + * Reads a property list (key and element pairs) from the input stream. + * + * @param in + * the input stream that contains the properties file + * + * @throws IOException + * Signals that an I/O exception has occurred. + */ + void load(InputStream in) throws IOException; + + /** + * Writes this property list (key and element pairs) in this Properties table to + * the output stream in a format suitable for loading into a Properties table using the load method. + * + * @param out + * the output stream that contains the properties file + * @param comments + * a description of the property list (ex. "Encrypted Properties File"). + * + * @throws IOException + * Signals that an I/O exception has occurred. + */ + void store(OutputStream out, String comments) throws IOException; + + +} diff --git a/src/main/java/org/owasp/esapi/Encryptor.java b/src/main/java/org/owasp/esapi/Encryptor.java new file mode 100644 index 000000000..c1729a839 --- /dev/null +++ b/src/main/java/org/owasp/esapi/Encryptor.java @@ -0,0 +1,316 @@ +/** + * 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 © 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 + * @author kevin.w.wall@gmail.com + * @created 2007 + */ +package org.owasp.esapi; + +import javax.crypto.SecretKey; + +import org.owasp.esapi.crypto.CipherText; +import org.owasp.esapi.crypto.PlainText; +import org.owasp.esapi.errors.EncryptionException; +import org.owasp.esapi.errors.IntegrityException; + + +/** + * 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. + *

+ * 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: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
ESAPI Property NameESAPI.properties DefaultBuiltin DefaultMeaning
HttpUtilities.UploadDirC:\ESAPI\testUploadUploadDirFinal destination directory for uploaded files.
HttpUtilities.UploadTempDirC:\tempValue of system property java.io.tmpdirTemporary staging directory for uploaded files.
HttpUtilities.ApprovedUploadExtensions.pdf,.doc,.docx,.ppt,.pptx,.xls,.xlsx,.rtf,.txt,.jpg,.pn.pdf,.txt,.jpg,.pngComma separated allowed list of file suffixes that may be uploaded.
HttpUtilities.MaxUploadFileBytes50000005000000Total maximum upload file size for uploaded files per HTTP request.
HttpUtilities.MaxUploadFileCount2020Maximum total number of uploaded files per HTTP request.
HttpUtilities.FileUploadAllowAnonymousUsertruetrueControls 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: + *

+ *

+     * Cache-Control: no-store
+ * Cache-Control: no-cache
+ * Cache-Control: must-revalidate
+ * Expires: -1
+ *
+ *

+ * 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: + * + *

    + *
  1. 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.
  2. + *
  3. 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.
  4. + *
  5. Encode any CRLF characters included in log data in order to prevent log injection attacks.
  6. + *
  7. 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.
  8. + *
  9. Record the following information with each event:
  10. + *
      + *
    1. Identity of the user that caused the event.
    2. + *
    3. A description of the event (supplied by the caller).
    4. + *
    5. Whether the event succeeded or failed (indicated by the caller).
    6. + *
    7. Severity level of the event (indicated by the caller).
    8. + *
    9. That this is a security relevant event (indicated by the caller).
    10. + *
    11. Hostname or IP where the event occurred (and ideally the user's source IP as well).
    12. + *
    13. A date/time stamp.
    14. + *
    + *
+ * + * Custom logger implementations might also: + *
    + *
  1. Filter out any sensitive data specific to the current application or organization, such as credit cards, + * social security numbers, etc.
  2. + *
+ * + * 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: + *

+     *         cipher_alg/cipher_mode[bits]/padding_scheme
+     * 
+ * 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. + *

+ * Examples are: + *

+     *         "AES/ECB/NoPadding"        // Default for ESAPI Java 1.4 (insecure)
+     *         "AES/CBC/PKCS5Padding"    // Default for ESAPI Java 2.0
+     *         "DESede/OFB32/PKCS5Padding"
+     * 
+ * 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. + *

+ * For further details, see the "Advanced Usage" section of + * + * "Why Is OWASP Changing ESAPI Encryption?". + *

+ * @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 sessions = new HashSet(); + private Locale locale = null; + + /** + * {@inheritDoc} + */ + public void addRole(String role) throws AuthenticationException { + throw new RuntimeException("Invalid operation for the anonymous user"); + } + + /** + * {@inheritDoc} + */ + public void addRoles(Set newRoles) throws AuthenticationException { + throw new RuntimeException("Invalid operation for the anonymous user"); + } + + /** + * {@inheritDoc} + */ + public void changePassword(String oldPassword, String newPassword1, + String newPassword2) throws AuthenticationException, + EncryptionException { + throw new RuntimeException("Invalid operation for the anonymous user"); + } + + /** + * {@inheritDoc} + */ + public void disable() { + throw new RuntimeException("Invalid operation for the anonymous user"); + } + + /** + * {@inheritDoc} + */ + public void enable() { + throw new RuntimeException("Invalid operation for the anonymous user"); + } + + /** + * {@inheritDoc} + */ + public long getAccountId() { + return 0; + } + + /** + * {@inheritDoc} + */ + public String getAccountName() { + return "Anonymous"; + } + + /** + * Alias method that is equivalent to getAccountName() + * + * @return the name of the current user's account + */ + public String getName() { + return getAccountName(); + } + + /** + * {@inheritDoc} + */ + public String getCSRFToken() { + return csrfToken; + } + + /** + * {@inheritDoc} + */ + public Date getExpirationTime() { + return null; + } + + /** + * {@inheritDoc} + */ + public int getFailedLoginCount() { + return 0; + } + + /** + * {@inheritDoc} + */ + public Date getLastFailedLoginTime() throws AuthenticationException { + return null; + } + + /** + * {@inheritDoc} + */ + public String getLastHostAddress() { + return "unknown"; + } + + /** + * {@inheritDoc} + */ + public Date getLastLoginTime() { + return null; + } + + /** + * {@inheritDoc} + */ + public Date getLastPasswordChangeTime() { + return null; + } + + /** + * {@inheritDoc} + */ + public Set getRoles() { + return new HashSet(); + } + + /** + * {@inheritDoc} + */ + public String getScreenName() { + return "Anonymous"; + } + + /** + * {@inheritDoc} + */ + public void addSession(HttpSession s) { + } + + /** + * {@inheritDoc} + */ + public void removeSession(HttpSession s) { + } + + /** + * {@inheritDoc} + */ + public Set getSessions() { + return sessions; + } + + /** + * {@inheritDoc} + */ + public void incrementFailedLoginCount() { + throw new RuntimeException("Invalid operation for the anonymous user"); + } + + /** + * {@inheritDoc} + */ + public boolean isAnonymous() { + return true; + } + + /** + * {@inheritDoc} + */ + public boolean isEnabled() { + return false; + } + + /** + * {@inheritDoc} + */ + public boolean isExpired() { + return false; + } + + /** + * {@inheritDoc} + */ + public boolean isInRole(String role) { + return false; + } + + /** + * {@inheritDoc} + */ + public boolean isLocked() { + return false; + } + + /** + * {@inheritDoc} + */ + public boolean isLoggedIn() { + return false; + } + + /** + * {@inheritDoc} + */ + public boolean isSessionAbsoluteTimeout() { + return false; + } + + /** + * {@inheritDoc} + */ + public boolean isSessionTimeout() { + return false; + } + + /** + * {@inheritDoc} + */ + public void lock() { + throw new RuntimeException("Invalid operation for the anonymous user"); + } + + /** + * {@inheritDoc} + */ + public void loginWithPassword(String password) + throws AuthenticationException { + throw new RuntimeException("Invalid operation for the anonymous user"); + } + + /** + * {@inheritDoc} + */ + public void logout() { + throw new RuntimeException("Invalid operation for the anonymous user"); + } + + /** + * {@inheritDoc} + */ + public void removeRole(String role) throws AuthenticationException { + throw new RuntimeException("Invalid operation for the anonymous user"); + } + + /** + * {@inheritDoc} + */ + public String resetCSRFToken() throws AuthenticationException { + csrfToken = ESAPI.randomizer().getRandomString(8, EncoderConstants.CHAR_ALPHANUMERICS); + return csrfToken; + } + + /** + * {@inheritDoc} + */ + public void setAccountName(String accountName) { + throw new RuntimeException("Invalid operation for the anonymous user"); + } + + /** + * {@inheritDoc} + */ + public void setExpirationTime(Date expirationTime) { + throw new RuntimeException("Invalid operation for the anonymous user"); + } + + /** + * {@inheritDoc} + */ + public void setRoles(Set roles) throws AuthenticationException { + throw new RuntimeException("Invalid operation for the anonymous user"); + } + + /** + * {@inheritDoc} + */ + public void setScreenName(String screenName) { + throw new RuntimeException("Invalid operation for the anonymous user"); + } + + /** + * {@inheritDoc} + */ + public void unlock() { + throw new RuntimeException("Invalid operation for the anonymous user"); + } + + /** + * {@inheritDoc} + */ + public boolean verifyPassword(String password) throws EncryptionException { + throw new RuntimeException("Invalid operation for the anonymous user"); + } + + /** + * {@inheritDoc} + */ + public void setLastFailedLoginTime(Date lastFailedLoginTime) { + throw new RuntimeException("Invalid operation for the anonymous user"); + } + + /** + * {@inheritDoc} + */ + public void setLastLoginTime(Date lastLoginTime) { + throw new RuntimeException("Invalid operation for the anonymous user"); + } + + /** + * {@inheritDoc} + */ + public void setLastHostAddress(String remoteHost) { + throw new RuntimeException("Invalid operation for the anonymous user"); + } + + /** + * {@inheritDoc} + */ + public void setLastPasswordChangeTime(Date lastPasswordChangeTime) { + throw new RuntimeException("Invalid operation for the anonymous user"); + } + + /** + * {@inheritDoc} + */ + public HashMap getEventMap() { + throw new RuntimeException("Invalid operation for the anonymous user"); + } + /** + * @return the locale + */ + public Locale getLocale() { + return locale; + } + + /** + * @param locale the locale to set + */ + public void setLocale(Locale locale) { + this.locale = locale; + } + }; +} diff --git a/src/main/java/org/owasp/esapi/ValidationErrorList.java b/src/main/java/org/owasp/esapi/ValidationErrorList.java new file mode 100644 index 000000000..d671f9479 --- /dev/null +++ b/src/main/java/org/owasp/esapi/ValidationErrorList.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 - 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.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.owasp.esapi.errors.ValidationException; + +/** + * 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: + * + *

+ * ValidationErrorList() errorList = new ValidationErrorList();
+ * String name  = ESAPI.validator().getValidInput("Name", form.getName(), "SomeESAPIRegExName1", 255, false, errorList);
+ * String address = ESAPI.validator().getValidInput("Address", form.getAddress(), "SomeESAPIRegExName2", 255, false, errorList);
+ * Integer weight = getValidInteger("Weight", form.getWeight(), 1, 1000000000, false, errorList);
+ * Integer sortOrder = getValidInteger("Sort Order", form.getSortOrder(), -100000, +100000, false, errorList);
+ * request.setAttribute( "ERROR_LIST", errorList );
+ * 
+ * + * The at your view layer you would be able to retrieve all + * of your error messages via a helper function like: + * + *
+ * public static ValidationErrorList getErrors() {
+ *     HttpServletRequest request = ESAPI.httpUtilities().getCurrentRequest();
+ *     ValidationErrorList errors = new ValidationErrorList();
+ *     if (request.getAttribute(Constants.ERROR_LIST) != null) {
+ *        errors = (ValidationErrorList)request.getAttribute("ERROR_LIST");
+ *     }
+ *        return errors;
+ * }
+ * 
+ * + * You can list all errors like: + * + *
+ * <%
+ *      for (Object vo : errorList.errors()) {
+ *         ValidationException ve = (ValidationException)vo;
+ * %>
+ * <%= ESAPI.encoder().encodeForHTML(ve.getMessage()) %>
+ * <% + * } + * %> + *
+ * + * And even check if a specific UI component is in error via calls like: + * + *
+ * ValidationException e = errorList.getError("Name");
+ * 
+ * + * @author Jim Manico (jim@manico.net) Manico.net + * @since August 15, 2008 + */ +public class ValidationErrorList { + + /** + * Error list of ValidationException's + */ + private HashMap errorList = new HashMap(); + + /** + * Adds a new error to list with a unique named context. + * No action taken if either element is null. + * Existing contexts will be overwritten. + * + * @param context Unique named context for this {@code ValidationErrorList}. + * @param vex A {@code ValidationException}. + */ + public void addError(String context, ValidationException vex) { + if ( context == null ) throw new RuntimeException( "Context cannot be null: " + vex.getLogMessage(), vex ); + if ( vex == null ) throw new RuntimeException( "ValidationException cannot be null for context (" + context + ")" ); + if (getError(context) != null) throw new RuntimeException("Context (" + context + ") already exists, must be unique"); + errorList.put(context, vex); + } + + /** + * Returns list of ValidationException, or empty list of no errors exist. + * + * @return List + */ + public List errors() { + return new ArrayList( errorList.values() ); + } + + /** + * Retrieves ValidationException for given context if one exists. + * + * @param context unique name for each error + * @return ValidationException or null for given context + */ + public ValidationException getError(String context) { + if (context == null) return null; + return errorList.get(context); + } + + /** + * Returns true if no error are present. + * + * @return boolean + */ + public boolean isEmpty() { + return errorList.isEmpty(); + } + + /** + * Returns the numbers of errors present. + * + * @return boolean + */ + public int size() { + return errorList.size(); + } +} diff --git a/src/main/java/org/owasp/esapi/ValidationRule.java b/src/main/java/org/owasp/esapi/ValidationRule.java new file mode 100644 index 000000000..2d93c3dbe --- /dev/null +++ b/src/main/java/org/owasp/esapi/ValidationRule.java @@ -0,0 +1,100 @@ +package org.owasp.esapi; + +import java.util.Set; + +import org.owasp.esapi.errors.ValidationException; + +/** + * A ValidationRule performs syntax and possibly semantic validation of a single piece of data from an untrusted source. + * + * @since ESAPI 2.0GA + */ +public interface ValidationRule { + + /** + * Parse the input, throw exceptions if validation fails + * + * @param context + * for logging + * @param input + * the value to be parsed + * @return a validated value + * @throws ValidationException + * Thrown if any validation rules fail, except when the + * {@code ESAPI.properties}> property + * "Validator.HtmlValidationAction" is set to + * {@code clean}. The default {@code ESAPI.properties}> property file + * has "Validator.HtmlValidationAction" is set to {@code throw}, which results + * in a {@code ValidationException} being thrown if any of the validation rules + * fail. + * + * releases. See ESAPI GitHub Issues + * 521 + * for futher details. + * + * @see #getValid(String context, String input, ValidationErrorList errorList) + */ + Object getValid(String context, String input) + throws ValidationException; + + /** + * Whether or not a valid valid can be null. {@code getValid} will throw an + * Exception and {#code getSafe} will return the default value if flag is set to + * true + * + * @param flag + * whether or not null values are valid/safe + */ + void setAllowNull(boolean flag); + + /** + * Programmatically supplied name for the validator + * @return a name, describing the validator + */ + String getTypeName(); + + /** + * @param typeName a name, describing the validator + */ + void setTypeName(String typeName); + + /** + * @param encoder the encoder to use + */ + void setEncoder(Encoder encoder); + + /** + * Check if the input is valid, throw an Exception otherwise + */ + void assertValid(String context, String input) + throws ValidationException; + + /** + * Get a validated value, add the errors to an existing error list + */ + Object getValid(String context, String input, + ValidationErrorList errorList) throws ValidationException; + + /** + * Try to call {@code getvalid}, then call a 'sanitize' method for sanitization (if one exists), + * finally return a default value. + */ + Object getSafe(String context, String input); + + /** + * @return true if the input passes validation + */ + boolean isValid(String context, String input); + + /** + * String the input of all chars contained in the list + */ + String whitelist(String input, char[] list); + + /** + * String the input of all chars contained in the list + */ + String whitelist(String input, Set list); + +} diff --git a/src/main/java/org/owasp/esapi/Validator.java b/src/main/java/org/owasp/esapi/Validator.java new file mode 100644 index 000000000..90eaa35ae --- /dev/null +++ b/src/main/java/org/owasp/esapi/Validator.java @@ -0,0 +1,1194 @@ +/* + * OWASP Enterprise Security API (ESAPI) + * + * This file is part of the Open Worldwide 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.io.InputStream; +import java.net.URI; +import java.text.DateFormat; +import java.util.Date; +import java.util.List; +import java.util.Set; + +import javax.servlet.http.HttpServletRequest; + +import org.owasp.esapi.errors.IntrusionException; +import org.owasp.esapi.errors.ValidationException; + + +/** + * 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 "allow-list" 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. + *

+ * CAUTION: There are many methods that take multiple (or only!) {@code String} + * arguments. Be careful that you do not mix up the order of these, because for + * several methods that have {@code context} and {@code input} arguments, mixing up + * the order of those likely will result in serious security consequences. + * . When there are 2 these {@code String} parameters—{@code context} and + * {@code input} arguments—the {@code context} argument is always first. + * See the individual method documentation for additional details. + *

+ * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @since June 1, 2007 + */ +public interface Validator { + + /** + * Add a validation rule to the registry using the "type name" of the rule as the key. + * @param rule The {@link ValidationRule} to add. + */ + void addRule( ValidationRule rule ); + + /** + * Get a validation rule from the registry with the "type name" of the rule as the key. + * @param name The "type" name of a {@link ValidationRule} to retrieve. + */ + ValidationRule getRule( String name ); + + /** + * Returns true if canonicalized input is valid. + *

+ * Calls {@link #getValidInput(String, String, String, int, boolean, boolean)} with {@code canonicalize=true} + * and returns true if no exceptions are thrown. + * + * @param 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. + * @param input + * The actual user input data to validate. + * @param type + * The regular expression name which maps to the actual regular expression from "ESAPI.properties". + * @param maxLength + * The maximum {@code String} length allowed for {@code input}. + * @param allowNull + * If {@code allowNull} is true then an input that is NULL or an empty string will be legal. + * If {@code allowNull} is false then NULL or an empty String will throw a ValidationException. + * @throws IntrusionException Input likely indicates an attack. + */ + boolean isValidInput(String context, String input, String type, int maxLength, boolean allowNull) throws IntrusionException; + + /** + * Returns true if canonicalized input is valid, + * any validation exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #getValidInput(String, String, String, int, boolean, boolean)} with {@code canonicalize=true} + * and returns true if no exceptions are thrown. + * + * @param 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. + * @param input + * The actual user input data to validate. + * @param type + * The regular expression name which maps to the actual regular expression from "ESAPI.properties". + * @param maxLength + * The maximum {@code String} length allowed for {@code input}. + * @param allowNull + * If {@code allowNull} is true then an input that is NULL or an empty string will be legal. + * If {@code allowNull} is false then NULL or an empty String will throw a ValidationException. + * @param errorList The error list to which any {@code ValidationException} messages are added. + * + * @throws IntrusionException Input likely indicates an attack. + */ + boolean isValidInput(String context, String input, String type, int maxLength, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; + + /** + * Returns true if {@code input} is valid. + *

+ * Calls {@link #getValidInput(String, String, String, int, boolean, boolean)} + * and returns true if no exceptions are thrown. + * + * @param 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. + * @param input + * The actual user input data to validate. + * @param type + * The regular expression name which maps to the actual regular expression from "ESAPI.properties". + * @param maxLength + * The maximum {@code String} length allowed for {@code input}. + * @param allowNull + * If {@code allowNull} is true then an input that is NULL or an empty string will be legal. + * If {@code allowNull} is false then NULL or an empty String will throw a ValidationException. + * @param canonicalize + * If true, the {@code input} if first canonicalized before being validated. + * + * @throws IntrusionException Input likely indicates an attack. + */ + boolean isValidInput(String context, String input, String type, int maxLength, boolean allowNull, boolean canonicalize) throws IntrusionException; + + /** + * Returns true if {@code input} is valid; + * any validation exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #getValidInput(String, String, String, int, boolean, boolean)} + * and returns true if no exceptions are thrown. + * + * @param 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. + * @param input + * The actual user input data to validate. + * @param type + * The regular expression name which maps to the actual regular expression from "ESAPI.properties". + * @param maxLength + * The maximum {@code String} length allowed for {@code input}. + * @param allowNull + * If {@code allowNull} is true then an input that is NULL or an empty string will be legal. + * If {@code allowNull} is false then NULL or an empty String will throw a ValidationException. + * @param canonicalize + * If true, the {@code input} if first canonicalized before being validated. + * @param errorList The error list to which any {@code ValidationException} messages are added. + * + * @throws IntrusionException Input likely indicates an attack. + */ + boolean isValidInput(String context, String input, String type, int maxLength, boolean allowNull, boolean canonicalize, ValidationErrorList errorList) throws IntrusionException; + + /** + * Returns the validated, canonicalized {@code input} as a String. + *

+ * Calls {@link #getValidInput(String, String, String, int, boolean, boolean)} + * with {@code canonicalize=true}. + * + * @param 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. + * @param input + * The actual user input data to validate. + * @param type + * The regular expression name which maps to the actual regular expression from "ESAPI.properties". + * @param maxLength + * The maximum {@code String} length allowed for {@code input}. + * @param allowNull + * If {@code allowNull} is true then an input that is NULL or an empty string will be legal. + * If {@code allowNull} is false then NULL or an empty String will throw a ValidationException. + * + * @throws ValidationException Input is invalid, based on the regex associated with {@code type}. + * @throws IntrusionException Input likely indicates an attack. + */ + String getValidInput(String context, String input, String type, int maxLength, boolean allowNull) throws ValidationException, IntrusionException; + + /** + * Returns validated {@code input} as a String with optional canonicalization. + *

+ * Invalid input will generate a descriptive ValidationException, + * and input that is clearly an attack will generate a descriptive IntrusionException. + * + * @param 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. + * @param input + * The actual user input data to validate. + * @param type + * The regular expression name which maps to the actual regular expression from "ESAPI.properties". + * @param maxLength + * The maximum post-canonicalized String length allowed. + * @param allowNull + * If {@code allowNull} is true then an input that is NULL or an empty string will be legal. + * If {@code allowNull} is false then NULL or an empty String will throw a ValidationException. + * @param canonicalize + * If canonicalize is true then input will be canonicalized before validation. + * + * @return The canonicalized user input. + * + * @throws ValidationException Input is invalid, based on the regex associated with {@code type}. + * @throws IntrusionException Input likely indicates an attack. + */ + String getValidInput(String context, String input, String type, int maxLength, boolean allowNull, boolean canonicalize) throws ValidationException, IntrusionException; + + /** + * Returns canonicalized validated {@code input} as a String, + * and adds validation exceptions to the supplied {@code errorList}. + *

+ * Calls {@link #getValidInput(String, String, String, int, boolean, boolean)}. + * + * @throws IntrusionException Input likely indicates an attack. + */ + String getValidInput(String context, String input, String type, int maxLength, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; + + /** + * Returns validated {@code input} as a String with optional canonicalization, + * and adds validation exceptions to the supplied {@code errorList}. + *

+ * Returns the result of calling {@link #getValidInput(String, String, String, int, boolean, boolean)} + * with {@code canonicalize=true}. + * + * @throws IntrusionException Input likely indicates an attack. + */ + String getValidInput(String context, String input, String type, int maxLength, boolean allowNull, boolean canonicalize, ValidationErrorList errorList) throws IntrusionException; + + /** + * Returns true if {@code input} is valid. + *

+ * Calls {@link #getValidDate(String, String, DateFormat, boolean)}, + * and returns true if no exceptions are thrown. + * + * @throws IntrusionException Input likely indicates an attack. + */ + boolean isValidDate(String context, String input, DateFormat format, boolean allowNull) throws IntrusionException; + + /** + * Returns true if {@code input} is valid, + * any validation exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #getValidDate(String, String, DateFormat, boolean)} + * and returns true if no exceptions are thrown. + * + * @throws IntrusionException Input likely indicates an attack. + */ + boolean isValidDate(String context, String input, DateFormat format, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; + + /** + * Returns a valid date as a {@link java.util.Date}. + *

+ * Invalid input will generate a descriptive ValidationException, + * and input that is clearly an attack will generate a descriptive IntrusionException. + * + * @param 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. + * @param input + * The actual user input data to validate. + * @param format + * Required formatting of date inputted. + * @param allowNull + * If {@code allowNull} is true then an input that is NULL or an empty string will be legal. + * If {@code allowNull} is false then NULL or an empty String will throw a ValidationException. + * + * @return A valid date as a {@link java.util.Date} + * + * @throws ValidationException Input is invalid, based on the regex associated with {@code type}. + * @throws IntrusionException Input likely indicates an attack. + */ + Date getValidDate(String context, String input, DateFormat format, boolean allowNull) throws ValidationException, IntrusionException; + + /** + * Returns a valid date as a {@link java.util.Date}, + * any validation exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #getValidDate(String, String, DateFormat, boolean)}. + * + * @throws IntrusionException Input likely indicates an attack. + */ + Date getValidDate(String context, String input, DateFormat format, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; + + /** + * Canonicalize and then sanitize the input so that it is "safe" for rendering in an HTML context (i.e., that + * it does not contain unwanted scripts in the body, attributes, CSS, URLs, or anywhere else). Note that the resulting + * returned value may omit input that is considered dangerous and cannot be safely sanitized and other input + * that gets HTML encoded (e.g., a single quote (') might get changed to """). + *

+ * The default behavior of this check depends on the {@code antisamy-esapi.xml} AntiSamy policy configuration file + * (or an alternate filename, specified via the "Validator.HtmlValidationConfigurationFile" property in your + * {@code ESAPI.properties} file. Implementors wishing to alter the AntiSamy policy configuration file should + * reference the OWASP AntiSamy project for ideas + * on how to do HTML validation in a allow-list way, as this is an extremely difficult problem. + * + * @param 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. + * @param input + * The actual user input data to validate. + * @param maxLength + * The maximum {@code String} length allowed for {@code input}. + * @param allowNull + * If {@code allowNull} is true then an input that is NULL or an empty string will be legal. + * If {@code allowNull} is false then NULL or an empty String will throw a ValidationException. + * + * @return A string representing the canonicalized and sanitized input that is safe for rendering in an HTML context. + * + * @throws ValidationException Input is invalid, based on the regex associated with {@code type}. + * @throws IntrusionException Input likely indicates an attack. + */ + String getValidSafeHTML(String context, String input, int maxLength, boolean allowNull) throws ValidationException, IntrusionException; + + /** + * Canonicalize and then sanitize the input so that it is "safe" for rendering in an HTML context (i.e., that + * it does not contain unwanted scripts in the body, attributes, CSS, URLs, or anywhere else). Note that the resulting + * returned value may omit input that is considered dangerous and cannot be safely sanitized and other input + * that gets HTML encoded (e.g., a single quote (') might get changed to """). + *

+ * The default behavior of this check depends on the {@code antisamy-esapi.xml} AntiSamy policy configuration file + * (or an alternate filename, specified via the "Validator.HtmlValidationConfigurationFile" property in your + * {@code ESAPI.properties} file. Implementors wishing to alter the AntiSamy policy configuration file should + * reference the OWASP AntiSamy project for ideas + * on how to do HTML validation in a allow-list way, as this is an extremely difficult problem. + *

+ * Calls {@link #getValidSafeHTML(String, String, int, boolean)}. + * + * @param 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. + * @param input + * The actual user input data to validate. + * @param maxLength + * The maximum {@code String} length allowed for {@code input}. + * @param allowNull + * If {@code allowNull} is true then an input that is NULL or an empty string will be legal. + * If {@code allowNull} is false then NULL or an empty String will throw a ValidationException. + * @param errorList The error list to which any {@code ValidationException} messages are added. + * + * @return A string representing the canonicalized and sanitized input that is safe for rendering in an HTML context. + * + * @throws IntrusionException Input likely indicates an attack. + */ + String getValidSafeHTML(String context, String input, int maxLength, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; + + /** + * Returns true if {@code input} matches the pattern for a valid credit card number. + *

+ * Calls {@link #getValidCreditCard(String, String, boolean)}, + * and returns true if no exceptions are thrown. + * + * @throws IntrusionException Input likely indicates an attack. + */ + boolean isValidCreditCard(String context, String input, boolean allowNull) throws IntrusionException; + + /** + * Returns true if {@code input} matches the pattern for a valid credit card number, + * any validation exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #getValidCreditCard(String, String, boolean)} + * and returns true if no exceptions are thrown. + * + * @throws IntrusionException Input likely indicates an attack. + */ + boolean isValidCreditCard(String context, String input, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; + + /** + * 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. + * + * @param context + * A descriptive name of the parameter that you are validating (e.g., PaymentPage_CreditCard). + * This value is used by any logging or error handling that is done with respect to the value passed in. + * @param input + * The actual user input data to validate. + * @param allowNull + * If {@code allowNull} is true then an input that is NULL or an empty string will be legal. + * If {@code allowNull} is false then NULL or an empty String will throw a ValidationException. + * + * @return A valid credit card number + * + * @throws ValidationException Input is invalid because it doesn't appear to be a valid credit card account number. + * @throws IntrusionException Input likely indicates an attack. + */ + String getValidCreditCard(String context, String input, boolean allowNull) throws ValidationException, IntrusionException; + + /** + * Returns a canonicalized and validated credit card number as a String, + * any validation exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #getValidCreditCard(String, String, boolean)}. + * + * @throws IntrusionException Input likely indicates an attack. + */ + String getValidCreditCard(String context, String input, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; + + /** + * Returns true if {@code input} is valid. + *

+ * Calls {@link #getValidDirectoryPath(String, String, File, boolean)}, + * and returns true if no exceptions are thrown. + * + * @throws IntrusionException Input likely indicates an attack. + */ + boolean isValidDirectoryPath(String context, String input, File parent, boolean allowNull) throws IntrusionException; + + /** + * Returns true if {@code input} is valid, + * any validation exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #getValidDirectoryPath(String, String, File, boolean)} + * and returns true if no exceptions are thrown. + * + * @throws IntrusionException Input likely indicates an attack. + */ + boolean isValidDirectoryPath(String context, String input, File parent, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; + + /** + * Returns a canonicalized and validated directory path as a String, provided that the input + * maps to an existing directory that is an existing subdirectory (at any level) of the specified parent. + *

+ * Invalid input will generate a descriptive ValidationException, + * and input that is clearly an attack will generate a descriptive IntrusionException. + * + * @param 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. + * @param input + * The actual input data to validate. + * @param allowNull + * If {@code allowNull} is true then an input that is NULL or an empty string will be legal. + * If {@code allowNull} is false then NULL or an empty String will throw a ValidationException. + * + * @return A valid directory path + * + * @throws ValidationException Input is invalid (e.g., the provided input is not a directory). + * @throws IntrusionException Input likely indicates an attack. + */ + String getValidDirectoryPath(String context, String input, File parent, boolean allowNull) throws ValidationException, IntrusionException; + + /** + * Returns a canonicalized and validated directory path as a String, provided that the input + * maps to an existing directory that is an existing subdirectory (at any level) of the specified parent; + * any validation exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #getValidDirectoryPath(String, String, File, boolean)}. + * + * @throws IntrusionException Input likely indicates an attack. + */ + String getValidDirectoryPath(String context, String input, File parent, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; + + /** + * Returns true if {@code input} is valid. + *

+ * Calls {@link #getValidFileName(String, String, List, boolean)} + * with allowedExtensions set to the configured {@code ESAPI.securityConfiguration().getAllowedFileExtensions()} + * and returns true if no exceptions are thrown. + * + * @throws IntrusionException Input likely indicates an attack. + * + * @see ESAPI#securityConfiguration() + * @see SecurityConfiguration#getAllowedFileExtensions() + */ + boolean isValidFileName(String context, String input, boolean allowNull) throws IntrusionException; + + /** + * Returns true if {@code input} is valid, + * any validation exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #getValidFileName(String, String, List, boolean)} + * with allowedExtensions set to the configured {@code ESAPI.securityConfiguration().getAllowedFileExtensions()} + * and returns true if no exceptions are thrown. + * + * @throws IntrusionException Input likely indicates an attack. + * + * @see ESAPI#securityConfiguration() + * @see SecurityConfiguration#getAllowedFileExtensions() + */ + boolean isValidFileName(String context, String input, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; + + /** + * Returns true if {@code input} is valid. + *

+ * Calls {@link #getValidFileName(String, String, List, boolean)}, + * and returns true if no exceptions are thrown. + * + * @throws IntrusionException Input likely indicates an attack. + * + * @see ESAPI#securityConfiguration() + * @see SecurityConfiguration#getAllowedFileExtensions() + */ + boolean isValidFileName(String context, String input, List allowedExtensions, boolean allowNull) throws IntrusionException; + + /** + * Returns true if {@code input} is valid, + * any validation exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #getValidFileName(String, String, List, boolean)} + * and returns true if no exceptions are thrown. + * + * @throws IntrusionException Input likely indicates an attack. + * + * @see ESAPI#securityConfiguration() + * @see SecurityConfiguration#getAllowedFileExtensions() + */ + boolean isValidFileName(String context, String input, List allowedExtensions, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; + + /** + * 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. + * + * @param 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. + * @param input + * The actual input data to validate. + * @param allowedExtensions + * List of file extensions which will be accepted. + * @param allowNull + * If {@code allowNull} is true then an input that is NULL or an empty string will be legal. + * If {@code allowNull} is false then NULL or an empty String will throw a ValidationException. + * + * @return A valid file name + * + * @throws ValidationException Input is invalid (e.g., {@code input} refers to a non-existant file, does not have a + * valid file extension as per {@code allowedExtensions}, does not match the canonicalized path, + * exceeds a maximum length of 255 characters, etc. + * @throws IntrusionException Input likely indicates an attack. + */ + String getValidFileName(String context, String input, List allowedExtensions, boolean allowNull) throws ValidationException, IntrusionException; + + /** + * Returns a canonicalized and validated file name as a String, + * any validation exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #getValidFileName(String, String, List, boolean)}, + * the supplied {@code errorList} is used to capture ValidationExceptions. + * + * @throws IntrusionException Input likely indicates an attack. + */ + String getValidFileName(String context, String input, List allowedExtensions, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; + + /** + * Returns true if {@code input} is valid. + *

+ * Calls {@link #getValidNumber(String, String, long, long, boolean)}, + * and returns true if no exceptions are thrown. + * + * @throws IntrusionException Input likely indicates an attack. + */ + boolean isValidNumber(String context, String input, long minValue, long maxValue, boolean allowNull) throws IntrusionException; + + /** + * Returns true if {@code input} is valid, + * any validation exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #getValidNumber(String, String, long, long, boolean)} + * and returns true if no exceptions are thrown. + * + * @throws IntrusionException Input likely indicates an attack. + */ + boolean isValidNumber(String context, String input, long minValue, long maxValue, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; + + /** + * 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. + * + * @param 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. + * @param input + * The actual input data to validate. + * @param allowNull + * If {@code allowNull} is true then an input that is NULL or an empty string will be legal. + * If {@code allowNull} is false then NULL or an empty String will throw a ValidationException. + * @param minValue + * Lowest legal value for input. + * @param maxValue + * Highest legal value for input. + * + * @return A validated number as a double. + * + * @throws ValidationException Input is invalid; that is, not a number in the range + * of [{@code minValue}, {@code maxValue}]. + * @throws IntrusionException Input likely indicates an attack. + */ + Double getValidNumber(String context, String input, long minValue, long maxValue, boolean allowNull) throws ValidationException, IntrusionException; + + /** + * Returns a validated number as a double within the range of + * [{@code minValue}, {@code maxValue}]; any validation + * exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #getValidNumber(String, String, long, long, boolean)}. + * + * @param context + * A descriptive name of the parameter that you are validating (e.g., "OrderPage_Quantity"). + * This value is used by any logging or error handling that is done with respect to the value passed in. + * @param input + * The actual user input data to validate. + * @param minValue + * Lowest legal value for input. + * @param maxValue + * Highest legal value for input. + * @param allowNull + * If {@code allowNull} is true then an input that is NULL or an empty string will be legal. + * If {@code allowNull} is false then NULL or an empty String will throw a ValidationException. + * @param errorList The error list to which any {@code ValidationException} messages are added. + * + * @throws IntrusionException Input likely indicates an attack. + */ + Double getValidNumber(String context, String input, long minValue, long maxValue, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; + + /** + * Returns true if {@code input} is a valid integer between {@code minValue} and {@code maxValue} inclusive. + *

+ * Calls {@link #getValidInteger(String, String, int, int, boolean)}, + * and returns true if no exceptions are thrown. + * + * @param context + * A descriptive name of the parameter that you are validating (e.g., "OrderPage_Quantity"). + * This value is used by any logging or error handling that is done with respect to the value passed in. + * @param input + * The actual user input data to validate. + * @param minValue + * Lowest legal value for input. + * @param maxValue + * Highest legal value for input. + * @param allowNull + * If {@code allowNull} is true then an input that is NULL or an empty string will be legal. + * If {@code allowNull} is false then NULL or an empty String will throw a ValidationException. + * + * @throws IntrusionException Input likely indicates an attack. + */ + boolean isValidInteger(String context, String input, int minValue, int maxValue, boolean allowNull) throws IntrusionException; + + /** + * Returns true if {@code input} is a valid integer between {@code minValue} and {@code maxValue} inclusive, + * any validation exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #getValidInteger(String, String, int, int, boolean)} + * and returns true if no exceptions are thrown. + * + * @param context + * A descriptive name of the parameter that you are validating (e.g., "OrderPage_Quantity"). + * This value is used by any logging or error handling that is done with respect to the value passed in. + * @param input + * The actual user input data to validate. + * @param minValue + * Lowest legal value for input. + * @param maxValue + * Highest legal value for input. + * @param allowNull + * If {@code allowNull} is true then an input that is NULL or an empty string will be legal. + * If {@code allowNull} is false then NULL or an empty String will throw a ValidationException. + * @param errorList The error list to which any {@code ValidationException} messages are added. + * + * @throws IntrusionException Input likely indicates an attack. + */ + boolean isValidInteger(String context, String input, int minValue, int maxValue, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; + + /** + * Returns a validated integer, + * {@code input} is a valid integer if it is between {@code minValue} and {@code maxValue} inclusive. + * Invalid input will generate a descriptive ValidationException, + * and input that is clearly an attack will generate a descriptive IntrusionException. + * + * @param context + * A descriptive name of the parameter that you are validating (e.g., OrderPage_Quantity). + * This value is used by any logging or error handling that is done with respect to the value passed in. + * @param input + * The actual input data to validate. + * @param allowNull + * If {@code allowNull} is true then an input that is NULL or an empty string will be legal. + * If {@code allowNull} is false then NULL or an empty String will throw a ValidationException. + * @param minValue + * Lowest legal value for input. + * @param maxValue + * Highest legal value for input. + * + * @return A validated number as an integer. + * + * @throws ValidationException Input is not a valid integer in the range of [{@code minValue}, {@code maxValue}]. + * @throws IntrusionException Input likely indicates an attack. + */ + Integer getValidInteger(String context, String input, int minValue, int maxValue, boolean allowNull) throws ValidationException, IntrusionException; + + /** + * Returns a validated integer, + * any validation exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #getValidInteger(String, String, int, int, boolean)}. + * + * @throws IntrusionException Input likely indicates an attack. + */ + Integer getValidInteger(String context, String input, int minValue, int maxValue, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; + + /** + * Returns true if {@code input} is valid. + *

+ * Calls {@link #getValidDouble(String, String, double, double, boolean)}, + * and returns true if no exceptions are thrown. + * + * @throws IntrusionException Input likely indicates an attack. + */ + boolean isValidDouble(String context, String input, double minValue, double maxValue, boolean allowNull) throws IntrusionException; + + /** + * Returns true if {@code input} is valid, + * any validation exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #getValidDouble(String, String, double, double, boolean)} + * and returns true if no exceptions are thrown. + * + * @throws IntrusionException Input likely indicates an attack. + */ + boolean isValidDouble(String context, String input, double minValue, double maxValue, boolean allowNull, ValidationErrorList errorList) throws 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. + * + * @param 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. + * @param input + * The actual input data to validate. + * @param allowNull + * If {@code allowNull} is true then an input that is NULL or an empty string will be legal. + * If {@code allowNull} is false then NULL or an empty String will throw a ValidationException. + * @param minValue + * Lowest legal value for input. + * @param maxValue + * Highest legal value for input. + * + * @return A validated real number as a double. + * + * @throws ValidationException Input is invalid. + * @throws IntrusionException Input likely indicates an attack. + */ + Double getValidDouble(String context, String input, double minValue, double maxValue, boolean allowNull) throws ValidationException, IntrusionException; + + /** + * Returns a validated real number as a double, + * any validation exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #getValidDouble(String, String, double, double, boolean)}, + * the supplied {@code errorList} is used to capture ValidationExceptions. + * + * @throws IntrusionException Input likely indicates an attack. + */ + Double getValidDouble(String context, String input, double minValue, double maxValue, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; + + /** + * Returns true if {@code input} is valid. + *

+ * Calls {@link #getValidFileContent(String, byte[], int, boolean)}, + * and returns true if no exceptions are thrown. + * + * @throws IntrusionException Input likely indicates an attack. + */ + boolean isValidFileContent(String context, byte[] input, int maxBytes, boolean allowNull) throws IntrusionException; + + /** + * Returns true if {@code input} is valid, + * any validation exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #getValidFileContent(String, byte[], int, boolean)} + * and returns true if no exceptions are thrown. + * + * @throws IntrusionException Input likely indicates an attack. + */ + boolean isValidFileContent(String context, byte[] input, int maxBytes, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; + + /** + * 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. + * + * @param 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. + * @param input + * The actual input data to validate. + * @param maxBytes + * The maximum number of bytes allowed in a legal file. + * @param allowNull + * If {@code allowNull} is true then an input that is NULL or an empty string will be legal. + * If {@code allowNull} is false then NULL or an empty String will throw a ValidationException. + * + * @return A byte array containing valid file content. + * + * @throws ValidationException Input is invalid. + * @throws IntrusionException Input likely indicates an attack. + */ + byte[] getValidFileContent(String context, byte[] input, int maxBytes, boolean allowNull) throws ValidationException, IntrusionException; + + /** + * Returns validated file content as a byte array, + * any validation exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #getValidFileContent(String, byte[], int, boolean)}, + * the supplied {@code errorList} is used to capture ValidationExceptions. + * + * @throws IntrusionException Input likely indicates an attack. + */ + byte[] getValidFileContent(String context, byte[] input, int maxBytes, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; + + /** + * Returns true if {@code filepath}, {@code filename}, and {@code content} of a file are valid. + *

+ * Calls {@link #isValidFileName(String, String, boolean)}, + * {@link #isValidDirectoryPath(String, String, File, boolean)}, + * and {@link #isValidFileContent(String, byte[], int, boolean)}, + * and returns true if all three checks pass. + * + * @throws IntrusionException Input likely indicates an attack. + */ + boolean isValidFileUpload(String context, String filepath, String filename, File parent, byte[] content, int maxBytes, boolean allowNull) throws IntrusionException; + + /** + * Returns true if {@code filepath}, {@code filename}, and {@code content} of a file are valid, + * any validation exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #isValidFileName(String, String, boolean, ValidationErrorList)} + * {@link #isValidDirectoryPath(String, String, File, boolean, ValidationErrorList)} + * and {@link #isValidFileContent(String, byte[], int, boolean, ValidationErrorList)}, + * and returns true if all three checks pass. + * + * @throws IntrusionException Input likely indicates an attack. + */ + boolean isValidFileUpload(String context, String filepath, String filename, File parent, byte[] content, int maxBytes, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; + + /** + * Validates the {@code filepath}, {@code filename}, and {@code content} of a file. + * Invalid input will generate a descriptive ValidationException, + * and input that is clearly an attack will generate a descriptive IntrusionException. + * + * @param 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. + * @param filepath + * The file path of the uploaded file. + * @param filename + * The filename of the uploaded file + * @param content + * A byte array containing the content of the uploaded file. + * @param maxBytes + * The max number of bytes allowed for a legal file upload. + * @param allowNull + * If {@code allowNull} is true then an input that is NULL or an empty string will be legal. + * If {@code allowNull} is false then NULL or an empty String will throw a ValidationException. + * + * @throws ValidationException Input is invalid. + * @throws IntrusionException Input likely indicates an attack. + */ + void assertValidFileUpload(String context, String filepath, String filename, File parent, byte[] content, int maxBytes, List allowedExtensions, boolean allowNull) throws ValidationException, IntrusionException; + + /** + * Validates the {@code filepath}, {@code filename}, and {@code content} of a file, + * any validation exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #assertValidFileUpload(String, String, String, File, byte[], int, List, boolean)}, + * the supplied {@code errorList} is used to capture ValidationExceptions. + * + * @throws IntrusionException Input likely indicates an attack. + */ + void assertValidFileUpload(String context, String filepath, String filename, File parent, byte[] content, int maxBytes, List allowedExtensions, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; + + /** + * Returns true if {@code input} is valid. + *

+ * Calls {@link #getValidListItem(String, String, List)} + * and returns true if no exceptions are thrown. + * + * @throws IntrusionException Input likely indicates an attack. + */ + boolean isValidListItem(String context, String input, List list) throws IntrusionException; + + /** + * Returns true if {@code input} is valid, + * any validation exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #getValidListItem(String, String, List)} + * and returns true if no exceptions are thrown. + * + * @throws IntrusionException Input likely indicates an attack. + */ + boolean isValidListItem(String context, String input, List list, ValidationErrorList errorList) throws 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. + * + * @param 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. + * @param input + * The value to search 'list' for. + * @param list + * The list to search for 'input'. + * + * @return The list item that exactly matches the canonicalized input. + * + * @throws ValidationException Input is invalid. + * @throws IntrusionException Input likely indicates an attack. + */ + String getValidListItem(String context, String input, List list) throws ValidationException, IntrusionException; + + /** + * Returns the list item that exactly matches the canonicalized input, + * any validation exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #getValidListItem(String, String, List)} + * + * @throws IntrusionException Input likely indicates an attack. + */ + String getValidListItem(String context, String input, List list, ValidationErrorList errorList) throws IntrusionException; + + /** + * Returns true if only required and optional parameters are in the request. + *

+ * Calls {@link #assertValidHTTPRequestParameterSet(String, HttpServletRequest, Set, Set)} + * and returns true if no exceptions are thrown. + * + * @throws IntrusionException Input likely indicates an attack. + */ + boolean isValidHTTPRequestParameterSet(String context, HttpServletRequest request, Set required, Set optional) throws IntrusionException; + + /** + * Returns true if only required and optional parameters are in the request, + * any validation exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #assertValidHTTPRequestParameterSet(String, HttpServletRequest, Set, Set)} + * and returns true if no exceptions are thrown. + * + * @throws IntrusionException Input likely indicates an attack. + */ + boolean isValidHTTPRequestParameterSet(String context, HttpServletRequest request, Set required, Set optional, ValidationErrorList errorList) throws 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. + * + * @param 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. + * @param required + * parameters that are required to be in HTTP request + * @param optional + * additional parameters that may be in HTTP request + * + * @throws ValidationException Input is invalid. + * @throws IntrusionException Input likely indicates an attack. + */ + void assertValidHTTPRequestParameterSet(String context, HttpServletRequest request, Set required, Set optional) throws ValidationException, IntrusionException; + + /** + * Validates that the parameters in the current request contain all required parameters + * and only optional ones in addition, + * any validation exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #assertValidHTTPRequestParameterSet(String, HttpServletRequest, Set, Set)}. + * + * @throws IntrusionException Input likely indicates an attack. + */ + void assertValidHTTPRequestParameterSet(String context, HttpServletRequest request, Set required, Set optional, ValidationErrorList errorList) throws IntrusionException; + + /** + * Returns true if {@code input} is valid. + *

+ * Calls {@link #getValidPrintable(String, char[], int, boolean)} + * and returns true if no exceptions are thrown. + * + * @throws IntrusionException Input likely indicates an attack. + */ + boolean isValidPrintable(String context, char[] input, int maxLength, boolean allowNull) throws IntrusionException; + + /** + * Returns true if {@code input} is valid, + * any validation exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #getValidPrintable(String, char[], int, boolean)} + * and returns true if no exceptions are thrown. + * + * @throws IntrusionException Input likely indicates an attack. + */ + boolean isValidPrintable(String context, char[] input, int maxLength, boolean allowNull, ValidationErrorList errorList) throws 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. + * + * @param 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. + * @param input + * data to be returned as valid and printable + * @param maxLength + * Maximum number of bytes stored in 'input' + * @param allowNull + * If {@code allowNull} is true then an input that is NULL or an empty string will be legal. + * If {@code allowNull} is false then NULL or an empty String will throw a ValidationException. + * + * @return a byte array containing only printable characters, made up of data from 'input' + * + * @throws ValidationException Input is invalid. + */ + char[] getValidPrintable(String context, char[] input, int maxLength, boolean allowNull) throws ValidationException; + + /** + * Returns canonicalized and validated printable characters as a byte array, + * any validation exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #getValidPrintable(String, char[], int, boolean)}. + * + * @throws IntrusionException Input likely indicates an attack. + */ + char[] getValidPrintable(String context, char[] input, int maxLength, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; + + /** + * Returns true if {@code input} is valid. + *

+ * Calls {@link #getValidPrintable(String, String, int, boolean)} + * and returns true if no exceptions are thrown. + * + * @throws IntrusionException Input likely indicates an attack. + */ + boolean isValidPrintable(String context, String input, int maxLength, boolean allowNull) throws IntrusionException; + + /** + * Returns true if {@code input} is valid, + * any validation exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #getValidPrintable(String, String, int, boolean)} + * and returns true if no exceptions are thrown. + * + * @throws IntrusionException Input likely indicates an attack. + */ + boolean isValidPrintable(String context, String input, int maxLength, boolean allowNull, ValidationErrorList errorList) throws 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. + * + * @param 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. + * @param input + * data to be returned as valid and printable + * @param maxLength + * Maximum number of bytes stored in 'input' after canonicalization + * @param allowNull + * If {@code allowNull} is true then an input that is NULL or an empty string will be legal. + * If {@code allowNull} is false then NULL or an empty String will throw a ValidationException. + * + * @return a String containing only printable characters, made up of data from 'input' + * + * @throws ValidationException Input is invalid. + */ + String getValidPrintable(String context, String input, int maxLength, boolean allowNull) throws ValidationException; + + /** + * Returns canonicalized and validated printable characters as a String, + * any validation exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #getValidPrintable(String, String, int, boolean)}. + * + * @throws IntrusionException Input likely indicates an attack. + */ + String getValidPrintable(String context, String input, int maxLength, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; + + /** + * Returns true if {@code input} is valid. + *

+ * Calls {@link #getValidRedirectLocation(String, String, boolean)} + * and returns true if no exceptions are thrown. + */ + boolean isValidRedirectLocation(String context, String input, boolean allowNull); + + /** + * Returns true if {@code input} is valid, + * any validation exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #getValidRedirectLocation(String, String, boolean)} + * and returns true if no exceptions are thrown. + */ + boolean isValidRedirectLocation(String context, String input, boolean allowNull, ValidationErrorList errorList); + + /** + * 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. + * + * @param 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. + * @param input + * redirect location to be returned as valid, according to encoding rules set in "ESAPI.properties" + * @param allowNull + * If {@code allowNull} is true then an input that is NULL or an empty string will be legal. + * If {@code allowNull} is false then NULL or an empty String will throw a ValidationException. + * + * @return A canonicalized and validated redirect location, as defined in "ESAPI.properties" + * + * @throws ValidationException Input is invalid. + * @throws IntrusionException Input likely indicates an attack. + */ + String getValidRedirectLocation(String context, String input, boolean allowNull) throws ValidationException, IntrusionException; + + /** + * Returns a canonicalized and validated redirect location as a String, + * any validation exceptions are added to the supplied {@code errorList}. + *

+ * Calls {@link #getValidRedirectLocation(String, String, boolean)}. + * + * @throws IntrusionException Input likely indicates an attack. + */ + String getValidRedirectLocation(String context, String input, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; + + /** + * 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. + * + * @param inputStream + * The InputStream from which to read data + * @param maxLength + * Maximum characters allowed to be read in per line + * + * @return a String containing the current line of inputStream + * + * @throws ValidationException Input is invalid. + */ + String safeReadLine(InputStream inputStream, int maxLength) throws ValidationException; + + /** + * Parses and ensures that the URI in question is a valid RFC-3986 URI. This simplifies + * the kind of regex required for subsequent validation to mitigate regex-based DoS attacks. + * + * @see RFC-3986. + * + * @param 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. + * @param input + * redirect location to be returned as valid, according to encoding rules set in "ESAPI.properties" + * @param allowNull + * If {@code allowNull} is true then an input that is NULL or an empty string will be legal. + * If {@code allowNull} is false then NULL or an empty String will throw a ValidationException. + * + * @return True if the URI is valid + */ + boolean isValidURI(String context, String input, boolean allowNull); + + /** + * Will return a {@code URI} object that will represent a fully parsed and legal URI + * as specified in RFC-3986. + * + * @param input String + * @return URI object representing a parsed URI, or {@code null} if the URI was non-compliant in some way. + */ + URI getRfcCompliantURI(String input); + +} diff --git a/src/main/java/org/owasp/esapi/codecs/AbstractCharacterCodec.java b/src/main/java/org/owasp/esapi/codecs/AbstractCharacterCodec.java new file mode 100644 index 000000000..8595cb6e1 --- /dev/null +++ b/src/main/java/org/owasp/esapi/codecs/AbstractCharacterCodec.java @@ -0,0 +1,47 @@ +/** + * 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) 2017 - 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 Matt Seil (mseil .at. owasp.org) + * @created 2017 + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @created 2007 + */ + +package org.owasp.esapi.codecs; + +/** + * + * This abstract Impl is broken off from the original {@code Codec} class and + * provides the {@code Character} parsing logic that has been with ESAPI from the beginning. + * + */ +public abstract class AbstractCharacterCodec extends AbstractCodec { + /* (non-Javadoc) + * @see org.owasp.esapi.codecs.Codec#decode(java.lang.String) + */ + @Override + public String decode(String input) { + StringBuilder sb = new StringBuilder(); + PushbackSequence pbs = new PushbackString(input); + while (pbs.hasNext()) { + Character c = decodeCharacter(pbs); + if (c != null) { + sb.append(c); + } else { + sb.append(pbs.next()); + } + } + return sb.toString(); + } +} diff --git a/src/main/java/org/owasp/esapi/codecs/AbstractCodec.java b/src/main/java/org/owasp/esapi/codecs/AbstractCodec.java new file mode 100644 index 000000000..5149b5d0a --- /dev/null +++ b/src/main/java/org/owasp/esapi/codecs/AbstractCodec.java @@ -0,0 +1,175 @@ +/** + * 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) 2017 - 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 Matt Seil (mseil .at. owasp.org) + * @created 2017 + */ +package org.owasp.esapi.codecs; + + +/** + * The {@code Coded} 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). {@code Coded}s 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. + *

+ * Be sure to see the several WARNINGs associated with the detailed + * method descriptions. You will not find that in the "Method Summary" section + * of the javadoc because that only shows the initial sentence. + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @param + * @since June 1, 2007 + * @see org.owasp.esapi.Encoder + */ +public abstract class AbstractCodec implements Codec { + + /** + * Initialize an array to mark which characters are to be encoded. Store the hex + * string for that character to save time later. If the character shouldn't be + * encoded, then store null. + */ + private final String[] hex = new String[256]; + + /** + * Default constructor + */ + public AbstractCodec() { + for ( char c = 0; c < 0xFF; c++ ) { + if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x5A || c >= 0x61 && c <= 0x7A ) { + hex[c] = null; + } else { + hex[c] = toHex(c).intern(); + } + } + } + + /** + * {@inheritDoc} + *

+ * WARNING!! {@code Character} based {@code Codec}s will only handle the byte range of + * 0-65535 (0x0-0xffff). Passing any data represented by a higher numerical value will result in + * a downcast thus destroying the original data with undefined results. + *

+ * Also, if you are implementing an {@code Integer} based codec, these will be silently discarded + * based on the return from {@code Character.isValidCodePoint( int )}. This is the preferred + * behavior moving forward. + */ + @Override + public String encode(char[] immune, String input) { + StringBuilder sb = new StringBuilder(); + for(int offset = 0; offset < input.length(); ) { + final int point = input.codePointAt(offset); + if (Character.isBmpCodePoint(point)) { + //We can then safely cast this to char and maintain legacy behavior. + sb.append(encodeCharacter(immune, new Character((char) point))); + } else { + sb.append(encodeCharacter(immune, point)); + } + offset += Character.charCount(point); + } + return sb.toString(); + } + + /** + * {@inheritDoc} + *

+ * WARNING!!!! Passing a standard {@code char} rather than {@code Character} to this method will resolve to the + * {@link #encodeCharacter( char[], char )} method, which will throw an {@code IllegalArgumentException} instead. + * YOU HAVE BEEN WARNED!!!! + */ + @Override + public String encodeCharacter( char[] immune, Character c ) { + return ""+c; + } + + + /** + * To prevent accidental usage and calling + * {@link #encodeCharacter( char[], int)} when called with {@code char} and + * {@code char} is first silently converted to {@code int} and then the + * unexpected method is called. + * + * @throws IllegalArgumentException to indicate that you called the incorrect method. + */ + public String encodeCharacter(char[] immune, char c) { + throw new IllegalArgumentException("You tried to call encodeCharacter() with a char. Nope. " + + "Use 'encodeCharacter( char[] immune, Character c)' instead!"); + } + + /* (non-Javadoc) + * @see org.owasp.esapi.codecs.Codec#encodeCharacter(char[], int) + */ + @Override + public String encodeCharacter( char[] immune, int codePoint ) { + String rval = ""; + if(Character.isValidCodePoint(codePoint)){ + rval = new StringBuilder().appendCodePoint(codePoint).toString(); + } + return rval; + } + + + + /* (non-Javadoc) + * @see org.owasp.esapi.codecs.Codec#decodeCharacter(org.owasp.esapi.codecs.PushbackString) + */ + @Override + public T decodeCharacter( PushbackSequence input ) { + return input.next(); + } + + /** + * {@inheritDoc} + */ + public String getHexForNonAlphanumeric(char c) { + if(c<0xFF) + return hex[c]; + return toHex(c); + } + + /** + * {@inheritDoc} + */ + public String getHexForNonAlphanumeric(int c) { + if (c<0xFF) { + return hex[c]; + } else { + return toHex(c); + } + } + + public String toOctal(char c) { + return Integer.toOctalString(c); + } + + public String toHex(char c) { + return Integer.toHexString(c); + } + + public String toHex(int c) { + return Integer.toHexString(c); + } + + /** + * {@inheritDoc} + */ + public boolean containsCharacter( char c, char[] array ) { + for (char ch : array) { + if (c == ch) return true; + } + return false; + } + +} diff --git a/src/main/java/org/owasp/esapi/codecs/AbstractIntegerCodec.java b/src/main/java/org/owasp/esapi/codecs/AbstractIntegerCodec.java new file mode 100644 index 000000000..5bf9038dd --- /dev/null +++ b/src/main/java/org/owasp/esapi/codecs/AbstractIntegerCodec.java @@ -0,0 +1,53 @@ +/** + * 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) 2017 - 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 Matt Seil (mseil .at. owasp.org) + * @created 2017 + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @created 2007 + */ +package org.owasp.esapi.codecs; + +/** + * This class is intended to be an alternative Abstract Implementation for parsing encoding + * data by focusing on {@code int} as opposed to {@code Character}. Because non-BMP code + * points cannot be represented by a {@code char}, this class remedies that by parsing string + * data as codePoints as opposed to a stream of {@code char}s. + * + * WARNING: This class will silently discard an invalid code point according to + * the result of {@code Character.isValidCodePoint( int )} method. + * + * @author Matt Seil (mseil .at. owasp.org) + * @since 2017 -- Adapted from Jeff Williams' original {@code Codec} class. + */ +public class AbstractIntegerCodec extends AbstractCodec { + + /** + * {@inheritDoc} + */ + @Override + public String decode(String input) { + StringBuilder sb = new StringBuilder(); + PushbackSequence pbs = new PushBackSequenceImpl(input); + while (pbs.hasNext()) { + Integer c = decodeCharacter(pbs); + if (c != null && Character.isValidCodePoint(c)) { + sb.appendCodePoint(c); + } else { + sb.appendCodePoint(pbs.next()); + } + } + return sb.toString(); + } +} diff --git a/src/main/java/org/owasp/esapi/codecs/AbstractPushbackSequence.java b/src/main/java/org/owasp/esapi/codecs/AbstractPushbackSequence.java new file mode 100644 index 000000000..31b338d90 --- /dev/null +++ b/src/main/java/org/owasp/esapi/codecs/AbstractPushbackSequence.java @@ -0,0 +1,70 @@ +/** + * 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) 2017 - 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 Matt Seil (mseil .at. owasp.org) + * @created 2017 + * + */ + +package org.owasp.esapi.codecs; + +/** + * This Abstract class provides the generic logic for using a {@link PushbackSequence} + * in regard to iterating strings. The final Impl is intended for the user to supply + * a type T such that the pushback interface can be utilized for sequences + * of type T. Presently this generic class is limited by the fact that + * input is a String. + * + * @author Matt Seil + * + * @param + */ +public abstract class AbstractPushbackSequence implements PushbackSequence { + protected String input; + protected T pushback; + protected T temp; + protected int index = 0; + protected int mark = 0; + + public AbstractPushbackSequence(String input) { + this.input = input; + } + + /** + * {@inheritDoc} + */ + public void pushback(T c) { + pushback = c; + } + + /** + * {@inheritDoc} + */ + public int index() { + return index; + } + + /** + * {@inheritDoc} + */ + public boolean hasNext() { + if (pushback != null) + return true; + if (input == null) + return false; + if (input.length() == 0) + return false; + if (index >= input.length()) + return false; + return true; + } +} diff --git a/src/org/owasp/esapi/codecs/Base64.java b/src/main/java/org/owasp/esapi/codecs/Base64.java similarity index 78% rename from src/org/owasp/esapi/codecs/Base64.java rename to src/main/java/org/owasp/esapi/codecs/Base64.java index a5a2130f4..0d7097afd 100644 --- a/src/org/owasp/esapi/codecs/Base64.java +++ b/src/main/java/org/owasp/esapi/codecs/Base64.java @@ -1,1815 +1,1646 @@ -package org.owasp.esapi.codecs; - -import org.owasp.esapi.ESAPI; -import org.owasp.esapi.Logger; - -/** - *

Encodes and decodes to and from Base64 notation.

- *

Homepage: http://iharder.net/base64.

- * - *

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:

- * - * String encoded = Base64.encodeBytes( mybytes, Base64.GZIP | Base64.DONT_BREAK_LINES ); - * - *

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: - *
      - *
    1. The default is RFC3548 format.
    2. - *
    3. 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
    4. - *
    5. 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
    6. - *
    - * 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. - *

- * - * @author Robert Harder - * @author rob@iharder.net - * @version 2.2.2 - */ -public class Base64 -{ - -/* ******** P U B L I C F I E L D S ******** */ - - - /** No options specified. Value is zero. */ - public final static int NO_OPTIONS = 0; - - /** Specify encoding. */ - public final static int ENCODE = 1; - - - /** Specify decoding. */ - public final static int DECODE = 0; - - - /** Specify that data should be gzip-compressed. */ - public final static int GZIP = 2; - - - /** Don't break lines when encoding (violates strict Base64 specification) */ - public final static int DONT_BREAK_LINES = 8; - - /** - * 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 final static int URL_SAFE = 16; - - - /** - * Encode using the special "ordered" dialect of Base64 described here: - * http://www.faqs.org/qa/rfcc-1940.html. - */ - public final static int ORDERED = 32; - - -/* ******** P R I V A T E F I E L D S ******** */ - - - /** Maximum line length (76) of Base64 output. */ - private final static int MAX_LINE_LENGTH = 76; - - - /** The equals sign (=) as a byte. */ - private final static byte EQUALS_SIGN = (byte)'='; - - - /** The new line character (\n) as a byte. */ - private final static byte NEW_LINE = (byte)'\n'; - - - /** Preferred encoding. */ - private final static String PREFERRED_ENCODING = "UTF-8"; - - - // I think I end up not using the BAD_ENCODING indicator. - //private final static byte BAD_ENCODING = -9; // Indicates error in encoding - private final static byte WHITE_SPACE_ENC = -5; // Indicates white space in encoding - private final static byte EQUALS_SIGN_ENC = -1; // Indicates equals sign in encoding - - private static final Logger logger = ESAPI.getLogger("Base64"); - - -/* ******** S T A N D A R D B A S E 6 4 A L P H A B E T ******** */ - - /** The 64 valid Base64 values. */ - //private final static byte[] ALPHABET; - /* Host platform me be something funny like EBCDIC, so we hardcode these values. */ - private final static byte[] _STANDARD_ALPHABET = - { - (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', - (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', - (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', - (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', - (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', - (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', - (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', - (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z', - (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', - (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'+', (byte)'/' - }; - - - /** - * Translates a Base64 value to either its 6-bit reconstruction value - * or a negative number indicating some other meaning. - **/ - private final static byte[] _STANDARD_DECODABET = - { - -9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 0 - 8 - -5,-5, // Whitespace: Tab and Linefeed - -9,-9, // Decimal 11 - 12 - -5, // Whitespace: Carriage Return - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 14 - 26 - -9,-9,-9,-9,-9, // Decimal 27 - 31 - -5, // Whitespace: Space - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 33 - 42 - 62, // Plus sign at decimal 43 - -9,-9,-9, // Decimal 44 - 46 - 63, // Slash at decimal 47 - 52,53,54,55,56,57,58,59,60,61, // Numbers zero through nine - -9,-9,-9, // Decimal 58 - 60 - -1, // Equals sign at decimal 61 - -9,-9,-9, // Decimal 62 - 64 - 0,1,2,3,4,5,6,7,8,9,10,11,12,13, // Letters 'A' through 'N' - 14,15,16,17,18,19,20,21,22,23,24,25, // Letters 'O' through 'Z' - -9,-9,-9,-9,-9,-9, // Decimal 91 - 96 - 26,27,28,29,30,31,32,33,34,35,36,37,38, // Letters 'a' through 'm' - 39,40,41,42,43,44,45,46,47,48,49,50,51, // Letters 'n' through 'z' - -9,-9,-9,-9 // Decimal 123 - 126 - /*,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 127 - 139 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */ - }; - - -/* ******** U R L S A F E B A S E 6 4 A L P H A B E T ******** */ - - /** - * Used in the URL- and Filename-safe dialect described in Section 4 of RFC3548: - * http://www.faqs.org/rfcs/rfc3548.html. - * Notice that the last two bytes become "hyphen" and "underscore" instead of "plus" and "slash." - */ - private final static byte[] _URL_SAFE_ALPHABET = - { - (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', - (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', - (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', - (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', - (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', - (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', - (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', - (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z', - (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', - (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'-', (byte)'_' - }; - - /** - * Used in decoding URL- and Filename-safe dialects of Base64. - */ - private final static byte[] _URL_SAFE_DECODABET = - { - -9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 0 - 8 - -5,-5, // Whitespace: Tab and Linefeed - -9,-9, // Decimal 11 - 12 - -5, // Whitespace: Carriage Return - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 14 - 26 - -9,-9,-9,-9,-9, // Decimal 27 - 31 - -5, // Whitespace: Space - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 33 - 42 - -9, // Plus sign at decimal 43 - -9, // Decimal 44 - 62, // Minus sign at decimal 45 - -9, // Decimal 46 - -9, // Slash at decimal 47 - 52,53,54,55,56,57,58,59,60,61, // Numbers zero through nine - -9,-9,-9, // Decimal 58 - 60 - -1, // Equals sign at decimal 61 - -9,-9,-9, // Decimal 62 - 64 - 0,1,2,3,4,5,6,7,8,9,10,11,12,13, // Letters 'A' through 'N' - 14,15,16,17,18,19,20,21,22,23,24,25, // Letters 'O' through 'Z' - -9,-9,-9,-9, // Decimal 91 - 94 - 63, // Underscore at decimal 95 - -9, // Decimal 96 - 26,27,28,29,30,31,32,33,34,35,36,37,38, // Letters 'a' through 'm' - 39,40,41,42,43,44,45,46,47,48,49,50,51, // Letters 'n' through 'z' - -9,-9,-9,-9 // Decimal 123 - 126 - /*,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 127 - 139 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */ - }; - - - -/* ******** O R D E R E D B A S E 6 4 A L P H A B E T ******** */ - - /** - * I don't get the point of this technique, but it is described here: - * http://www.faqs.org/qa/rfcc-1940.html. - */ - private final static byte[] _ORDERED_ALPHABET = - { - (byte)'-', - (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', - (byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9', - (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', - (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', - (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', - (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', - (byte)'_', - (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', - (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', - (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', - (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z' - }; - - /** - * Used in decoding the "ordered" dialect of Base64. - */ - private final static byte[] _ORDERED_DECODABET = - { - -9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 0 - 8 - -5,-5, // Whitespace: Tab and Linefeed - -9,-9, // Decimal 11 - 12 - -5, // Whitespace: Carriage Return - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 14 - 26 - -9,-9,-9,-9,-9, // Decimal 27 - 31 - -5, // Whitespace: Space - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 33 - 42 - -9, // Plus sign at decimal 43 - -9, // Decimal 44 - 0, // Minus sign at decimal 45 - -9, // Decimal 46 - -9, // Slash at decimal 47 - 1,2,3,4,5,6,7,8,9,10, // Numbers zero through nine - -9,-9,-9, // Decimal 58 - 60 - -1, // Equals sign at decimal 61 - -9,-9,-9, // Decimal 62 - 64 - 11,12,13,14,15,16,17,18,19,20,21,22,23, // Letters 'A' through 'M' - 24,25,26,27,28,29,30,31,32,33,34,35,36, // Letters 'N' through 'Z' - -9,-9,-9,-9, // Decimal 91 - 94 - 37, // Underscore at decimal 95 - -9, // Decimal 96 - 38,39,40,41,42,43,44,45,46,47,48,49,50, // Letters 'a' through 'm' - 51,52,53,54,55,56,57,58,59,60,61,62,63, // Letters 'n' through 'z' - -9,-9,-9,-9 // Decimal 123 - 126 - /*,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 127 - 139 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */ - }; - - -/* ******** D E T E R M I N E W H I C H A L H A B E T ******** */ - - - /** - * Returns one of the _SOMETHING_ALPHABET byte arrays depending on - * the options specified. - * It's possible, though silly, to specify ORDERED and URLSAFE - * in which case one of them will be picked, though there is - * no guarantee as to which one will be picked. - */ - private final static byte[] getAlphabet( int options ) - { - if( (options & URL_SAFE) == URL_SAFE ) return _URL_SAFE_ALPHABET; - else if( (options & ORDERED) == ORDERED ) return _ORDERED_ALPHABET; - else return _STANDARD_ALPHABET; - - } // end getAlphabet - - - /** - * Returns one of the _SOMETHING_DECODABET byte arrays depending on - * the options specified. - * It's possible, though silly, to specify ORDERED and URL_SAFE - * in which case one of them will be picked, though there is - * no guarantee as to which one will be picked. - */ - private final static byte[] getDecodabet( int options ) - { - if( (options & URL_SAFE) == URL_SAFE ) return _URL_SAFE_DECODABET; - else if( (options & ORDERED) == ORDERED ) return _ORDERED_DECODABET; - else return _STANDARD_DECODABET; - - } // end getAlphabet - - - - /** Defeats instantiation. */ - private Base64(){} - - - /** - * 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. - */ - public final static void main( String[] args ) - { - if( args.length < 3 ){ - usage("Not enough arguments."); - } // end if: args.length < 3 - else { - String flag = args[0]; - String infile = args[1]; - String outfile = args[2]; - if( flag.equals( "-e" ) ){ - Base64.encodeFileToFile( infile, outfile ); - } // end if: encode - else if( flag.equals( "-d" ) ) { - Base64.decodeFileToFile( infile, outfile ); - } // end else if: decode - else { - usage( "Unknown flag: " + flag ); - } // end else - } // end else - } // end main - - /** - * Prints command line usage. - * - * @param msg A message to include with usage info. - */ - private final static void usage( String msg ) - { - System.err.println( msg ); - System.err.println( "Usage: java Base64 -e|-d inputfile outputfile" ); - } // end usage - - -/* ******** E N C O D I N G M E T H O D S ******** */ - - - /** - * Encodes up to the first three bytes of array threeBytes - * and returns a four-byte array in Base64 notation. - * The actual number of significant bytes in your array is - * given by numSigBytes. - * The array threeBytes needs only be as big as - * numSigBytes. - * Code can reuse a byte array by passing a four-byte array as b4. - * - * @param b4 A reusable byte array to reduce array instantiation - * @param threeBytes the array to convert - * @param numSigBytes the number of significant bytes in your array - * @return four byte array in Base64 notation. - * @since 1.5.1 - */ - private static byte[] encode3to4( byte[] b4, byte[] threeBytes, int numSigBytes, int options ) - { - encode3to4( threeBytes, 0, numSigBytes, b4, 0, options ); - return b4; - } // end encode3to4 - - - /** - *

Encodes up to three bytes of the array source - * and writes the resulting four Base64 bytes to destination. - * The source and destination arrays can be manipulated - * anywhere along their length by specifying - * srcOffset and destOffset. - * This method does not check to make sure your arrays - * are large enough to accomodate srcOffset + 3 for - * the source array or destOffset + 4 for - * the destination array. - * The actual number of significant bytes in your array is - * given by numSigBytes.

- *

This is the lowest level of the encoding methods with - * all possible parameters.

- * - * @param source the array to convert - * @param srcOffset the index where conversion begins - * @param numSigBytes the number of significant bytes in your array - * @param destination the array to hold the conversion - * @param destOffset the index where output will be put - * @return the destination array - * @since 1.3 - */ - private static byte[] encode3to4( - byte[] source, int srcOffset, int numSigBytes, - byte[] destination, int destOffset, int options ) - { - byte[] ALPHABET = getAlphabet( options ); - - // 1 2 3 - // 01234567890123456789012345678901 Bit position - // --------000000001111111122222222 Array position from threeBytes - // --------| || || || | Six bit groups to index ALPHABET - // >>18 >>12 >> 6 >> 0 Right shift necessary - // 0x3f 0x3f 0x3f Additional AND - - // Create buffer with zero-padding if there are only one or two - // significant bytes passed in the array. - // We have to shift left 24 in order to flush out the 1's that appear - // when Java treats a value as negative that is cast from a byte to an int. - int inBuff = ( numSigBytes > 0 ? ((source[ srcOffset ] << 24) >>> 8) : 0 ) - | ( numSigBytes > 1 ? ((source[ srcOffset + 1 ] << 24) >>> 16) : 0 ) - | ( numSigBytes > 2 ? ((source[ srcOffset + 2 ] << 24) >>> 24) : 0 ); - - switch( numSigBytes ) - { - case 3: - destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ]; - destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ]; - destination[ destOffset + 2 ] = ALPHABET[ (inBuff >>> 6) & 0x3f ]; - destination[ destOffset + 3 ] = ALPHABET[ (inBuff ) & 0x3f ]; - return destination; - - case 2: - destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ]; - destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ]; - destination[ destOffset + 2 ] = ALPHABET[ (inBuff >>> 6) & 0x3f ]; - destination[ destOffset + 3 ] = EQUALS_SIGN; - return destination; - - case 1: - destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ]; - destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ]; - destination[ destOffset + 2 ] = EQUALS_SIGN; - destination[ destOffset + 3 ] = EQUALS_SIGN; - return destination; - - default: - return destination; - } // end switch - } // end encode3to4 - - - - /** - * 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. - * - * @param serializableObject The object to encode - * @return The Base64-encoded object - * @since 1.4 - */ - public static String encodeObject( java.io.Serializable serializableObject ) - { - return encodeObject( serializableObject, NO_OPTIONS ); - } // end encodeObject - - - - /** - * 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 - *

- * Example: encodeObject( myObj, Base64.GZIP | Base64.DONT_BREAK_LINES ) - * - * @param serializableObject The object to encode - * @param options Specified options - * @return The Base64-encoded object - * @see Base64#GZIP - * @see Base64#DONT_BREAK_LINES - * @since 2.0 - */ - public static String encodeObject( java.io.Serializable serializableObject, int options ) - { - // Streams - java.io.ByteArrayOutputStream baos = null; - java.io.OutputStream b64os = null; - java.io.ObjectOutputStream oos = null; - java.util.zip.GZIPOutputStream gzos = null; - - // Isolate options - int gzip = (options & GZIP); - int dontBreakLines = (options & DONT_BREAK_LINES); - - try - { - // ObjectOutputStream -> (GZIP) -> Base64 -> ByteArrayOutputStream - baos = new java.io.ByteArrayOutputStream(); - b64os = new Base64.OutputStream( baos, ENCODE | options ); - - // GZip? - if( gzip == GZIP ) - { - gzos = new java.util.zip.GZIPOutputStream( b64os ); - oos = new java.io.ObjectOutputStream( gzos ); - } // end if: gzip - else - oos = new java.io.ObjectOutputStream( b64os ); - - oos.writeObject( serializableObject ); - } // end try - catch( java.io.IOException e ) - { - logger.error( Logger.SECURITY, "Problem writing object", e ); - return null; - } // end catch - finally - { - try{ oos.close(); } catch( Exception e ){} - try{ gzos.close(); } catch( Exception e ){} - try{ b64os.close(); } catch( Exception e ){} - try{ baos.close(); } catch( Exception e ){} - } // end finally - - // Return value according to relevant encoding. - try - { - return new String( baos.toByteArray(), PREFERRED_ENCODING ); - } // end try - catch (java.io.UnsupportedEncodingException uue) - { - return new String( baos.toByteArray() ); - } // end catch - - } // end encode - - - - /** - * Encodes a byte array into Base64 notation. - * Does not GZip-compress data. - * - * @param source The data to convert - * @since 1.4 - */ - public static String encodeBytes( byte[] source ) - { - return encodeBytes( source, 0, source.length, NO_OPTIONS ); - } // end encodeBytes - - - - /** - * 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 - *

- * Example: encodeBytes( myData, Base64.GZIP | Base64.DONT_BREAK_LINES ) - * - * - * @param source The data to convert - * @param options Specified options - * @see Base64#GZIP - * @see Base64#DONT_BREAK_LINES - * @since 2.0 - */ - public static String encodeBytes( byte[] source, int options ) - { - return encodeBytes( source, 0, source.length, options ); - } // end encodeBytes - - - /** - * Encodes a byte array into Base64 notation. - * Does not GZip-compress data. - * - * @param source The data to convert - * @param off Offset in array where conversion should begin - * @param len Length of data to convert - * @since 1.4 - */ - public static String encodeBytes( byte[] source, int off, int len ) - { - return encodeBytes( source, off, len, NO_OPTIONS ); - } // end encodeBytes - - - - /** - * 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 - *

- * Example: encodeBytes( myData, Base64.GZIP | Base64.DONT_BREAK_LINES ) - * - * - * @param source The data to convert - * @param off Offset in array where conversion should begin - * @param len Length of data to convert - * @param options Specified options - * @param options alphabet type is pulled from this (standard, url-safe, ordered) - * @see Base64#GZIP - * @see Base64#DONT_BREAK_LINES - * @since 2.0 - */ - public static String encodeBytes( byte[] source, int off, int len, int options ) - { - // Isolate options - int dontBreakLines = ( options & DONT_BREAK_LINES ); - int gzip = ( options & GZIP ); - - // Compress? - if( gzip == GZIP ) - { - java.io.ByteArrayOutputStream baos = null; - java.util.zip.GZIPOutputStream gzos = null; - Base64.OutputStream b64os = null; - - - try - { - // GZip -> Base64 -> ByteArray - baos = new java.io.ByteArrayOutputStream(); - b64os = new Base64.OutputStream( baos, ENCODE | options ); - gzos = new java.util.zip.GZIPOutputStream( b64os ); - - gzos.write( source, off, len ); - gzos.close(); - } // end try - catch( java.io.IOException e ) - { - logger.error( Logger.SECURITY, "Problem writing gzip stream", e ); - return null; - } // end catch - finally - { - try{ gzos.close(); } catch( Exception e ){} - try{ b64os.close(); } catch( Exception e ){} - try{ baos.close(); } catch( Exception e ){} - } // end finally - - // Return value according to relevant encoding. - try - { - return new String( baos.toByteArray(), PREFERRED_ENCODING ); - } // end try - catch (java.io.UnsupportedEncodingException uue) - { - return new String( baos.toByteArray() ); - } // end catch - } // end if: compress - - // Else, don't compress. Better not to use streams at all then. - else - { - // Convert option to boolean in way that code likes it. - boolean breakLines = dontBreakLines == 0; - - int len43 = len * 4 / 3; - byte[] outBuff = new byte[ ( len43 ) // Main 4:3 - + ( (len % 3) > 0 ? 4 : 0 ) // Account for padding - + (breakLines ? ( len43 / MAX_LINE_LENGTH ) : 0) ]; // New lines - int d = 0; - int e = 0; - int len2 = len - 2; - int lineLength = 0; - for( ; d < len2; d+=3, e+=4 ) - { - encode3to4( source, d+off, 3, outBuff, e, options ); - - lineLength += 4; - if( breakLines && lineLength == MAX_LINE_LENGTH ) - { - outBuff[e+4] = NEW_LINE; - e++; - lineLength = 0; - } // end if: end of line - } // en dfor: each piece of array - - if( d < len ) - { - encode3to4( source, d+off, len - d, outBuff, e, options ); - e += 4; - } // end if: some padding needed - - - // Return value according to relevant encoding. - try - { - return new String( outBuff, 0, e, PREFERRED_ENCODING ); - } // end try - catch (java.io.UnsupportedEncodingException uue) - { - return new String( outBuff, 0, e ); - } // end catch - - } // end else: don't compress - - } // end encodeBytes - - - - - -/* ******** D E C O D I N G M E T H O D S ******** */ - - - /** - * Decodes four bytes from array source - * and writes the resulting bytes (up to three of them) - * to destination. - * The source and destination arrays can be manipulated - * anywhere along their length by specifying - * srcOffset and destOffset. - * This method does not check to make sure your arrays - * are large enough to accomodate srcOffset + 4 for - * the source array or destOffset + 3 for - * the destination array. - * This method returns the actual number of bytes that - * were converted from the Base64 encoding. - *

This is the lowest level of the decoding methods with - * all possible parameters.

- * - * - * @param source the array to convert - * @param srcOffset the index where conversion begins - * @param destination the array to hold the conversion - * @param destOffset the index where output will be put - * @param options alphabet type is pulled from this (standard, url-safe, ordered) - * @return the number of decoded bytes converted - * @since 1.3 - */ - private static int decode4to3( byte[] source, int srcOffset, byte[] destination, int destOffset, int options ) - { - byte[] DECODABET = getDecodabet( options ); - - // Example: Dk== - if( source[ srcOffset + 2] == EQUALS_SIGN ) - { - // Two ways to do the same thing. Don't know which way I like best. - //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) - // | ( ( DECODABET[ source[ srcOffset + 1] ] << 24 ) >>> 12 ); - int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 ) - | ( ( DECODABET[ source[ srcOffset + 1] ] & 0xFF ) << 12 ); - - destination[ destOffset ] = (byte)( outBuff >>> 16 ); - return 1; - } - - // Example: DkL= - else if( source[ srcOffset + 3 ] == EQUALS_SIGN ) - { - // Two ways to do the same thing. Don't know which way I like best. - //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) - // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 ) - // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 ); - int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 ) - | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 ) - | ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) << 6 ); - - destination[ destOffset ] = (byte)( outBuff >>> 16 ); - destination[ destOffset + 1 ] = (byte)( outBuff >>> 8 ); - return 2; - } - - // Example: DkLE - else - { - try{ - // Two ways to do the same thing. Don't know which way I like best. - //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) - // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 ) - // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 ) - // | ( ( DECODABET[ source[ srcOffset + 3 ] ] << 24 ) >>> 24 ); - int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 ) - | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 ) - | ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) << 6) - | ( ( DECODABET[ source[ srcOffset + 3 ] ] & 0xFF ) ); - - - destination[ destOffset ] = (byte)( outBuff >> 16 ); - destination[ destOffset + 1 ] = (byte)( outBuff >> 8 ); - destination[ destOffset + 2 ] = (byte)( outBuff ); - - return 3; - }catch( Exception e){ - logger.error( Logger.SECURITY, "Problem writing object", e ); - logger.error( Logger.SECURITY, ""+source[srcOffset]+ ": " + ( DECODABET[ source[ srcOffset ] ] ) ); - logger.error( Logger.SECURITY, ""+source[srcOffset+1]+ ": " + ( DECODABET[ source[ srcOffset + 1 ] ] ) ); - logger.error( Logger.SECURITY, ""+source[srcOffset+2]+ ": " + ( DECODABET[ source[ srcOffset + 2 ] ] ) ); - logger.error( Logger.SECURITY, ""+source[srcOffset+3]+ ": " + ( DECODABET[ source[ srcOffset + 3 ] ] ) ); - return -1; - } // end catch - } - } // end decodeToBytes - - - - - /** - * 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. - * - * @param source The Base64 encoded data - * @param off The offset of where to begin decoding - * @param len The length of characters to decode - * @return decoded data - * @since 1.3 - */ - public static byte[] decode( byte[] source, int off, int len, int options ) - { - byte[] DECODABET = getDecodabet( options ); - - int len34 = len * 3 / 4; - byte[] outBuff = new byte[ len34 ]; // Upper limit on size of output - int outBuffPosn = 0; - - byte[] b4 = new byte[4]; - int b4Posn = 0; - int i = 0; - byte sbiCrop = 0; - byte sbiDecode = 0; - for( i = off; i < off+len; i++ ) - { - sbiCrop = (byte)(source[i] & 0x7f); // Only the low seven bits - sbiDecode = DECODABET[ sbiCrop ]; - - if( sbiDecode >= WHITE_SPACE_ENC ) // White space, Equals sign or better - { - if( sbiDecode >= EQUALS_SIGN_ENC ) - { - b4[ b4Posn++ ] = sbiCrop; - if( b4Posn > 3 ) - { - outBuffPosn += decode4to3( b4, 0, outBuff, outBuffPosn, options ); - b4Posn = 0; - - // If that was the equals sign, break out of 'for' loop - if( sbiCrop == EQUALS_SIGN ) - break; - } // end if: quartet built - - } // end if: equals sign or better - - } // end if: white space, equals sign or better - else - { - logger.error( Logger.SECURITY, "Bad Base64 input character at " + i + ": " + source[i] + "(decimal)" ); - return null; - } // end else: - } // each input character - - byte[] out = new byte[ outBuffPosn ]; - System.arraycopy( outBuff, 0, out, 0, outBuffPosn ); - return out; - } // end decode - - - - - /** - * Decodes data from Base64 notation, automatically - * detecting gzip-compressed data and decompressing it. - * - * @param s the string to decode - * @return the decoded data - * @since 1.4 - */ - public static byte[] decode( String s ) - { - return decode( s, NO_OPTIONS ); - } - - - /** - * Decodes data from Base64 notation, automatically - * detecting gzip-compressed data and decompressing it. - * - * @param s the string to decode - * @param options encode options such as URL_SAFE - * @return the decoded data - * @since 1.4 - */ - public static byte[] decode( String s, int options ) - { - byte[] bytes; - try - { - bytes = s.getBytes( PREFERRED_ENCODING ); - } // end try - catch( java.io.UnsupportedEncodingException uee ) - { - bytes = s.getBytes(); - } // end catch - // - - // Decode - bytes = decode( bytes, 0, bytes.length, options ); - - - // Check to see if it's gzip-compressed - // GZIP Magic Two-Byte Number: 0x8b1f (35615) - if( bytes != null && bytes.length >= 4 ) - { - - int head = ((int)bytes[0] & 0xff) | ((bytes[1] << 8) & 0xff00); - if( java.util.zip.GZIPInputStream.GZIP_MAGIC == head ) - { - java.io.ByteArrayInputStream bais = null; - java.util.zip.GZIPInputStream gzis = null; - java.io.ByteArrayOutputStream baos = null; - byte[] buffer = new byte[2048]; - int length = 0; - - try - { - baos = new java.io.ByteArrayOutputStream(); - bais = new java.io.ByteArrayInputStream( bytes ); - gzis = new java.util.zip.GZIPInputStream( bais ); - - while( ( length = gzis.read( buffer ) ) >= 0 ) - { - baos.write(buffer,0,length); - } // end while: reading input - - // No error? Get new bytes. - bytes = baos.toByteArray(); - - } // end try - catch( java.io.IOException e ) - { - // Just return originally-decoded bytes - } // end catch - finally - { - try{ baos.close(); } catch( Exception e ){} - try{ gzis.close(); } catch( Exception e ){} - try{ bais.close(); } catch( Exception e ){} - } // end finally - - } // end if: gzipped - } // end if: bytes.length >= 2 - - return bytes; - } // end decode - - - - - /** - * Attempts to decode Base64 data and deserialize a Java - * Object within. Returns null if there was an error. - * - * @param encodedObject The Base64 data to decode - * @return The decoded and deserialized object - * @since 1.5 - */ - public static Object decodeToObject( String encodedObject ) - { - // Decode and gunzip if necessary - byte[] objBytes = decode( encodedObject ); - - java.io.ByteArrayInputStream bais = null; - java.io.ObjectInputStream ois = null; - Object obj = null; - - try - { - bais = new java.io.ByteArrayInputStream( objBytes ); - ois = new java.io.ObjectInputStream( bais ); - - obj = ois.readObject(); - } // end try - catch( java.io.IOException e ) - { - logger.error( Logger.SECURITY, "Problem reading object", e ); - obj = null; - } // end catch - catch( java.lang.ClassNotFoundException e ) - { - logger.error( Logger.SECURITY, "Problem reading object", e ); - obj = null; - } // end catch - finally - { - try{ bais.close(); } catch( Exception e ){} - try{ ois.close(); } catch( Exception e ){} - } // end finally - - return obj; - } // end decodeObject - - - - /** - * Convenience method for encoding data to a file. - * - * @param dataToEncode byte array of data to encode in base64 form - * @param filename Filename for saving encoded data - * @return true if successful, false otherwise - * - * @since 2.1 - */ - public static boolean encodeToFile( byte[] dataToEncode, String filename ) - { - boolean success = false; - Base64.OutputStream bos = null; - try - { - bos = new Base64.OutputStream( - new java.io.FileOutputStream( filename ), Base64.ENCODE ); - bos.write( dataToEncode ); - success = true; - } // end try - catch( java.io.IOException e ) - { - - success = false; - } // end catch: IOException - finally - { - try{ bos.close(); } catch( Exception e ){} - } // end finally - - return success; - } // end encodeToFile - - - /** - * Convenience method for decoding data to a file. - * - * @param dataToDecode Base64-encoded data as a string - * @param filename Filename for saving decoded data - * @return true if successful, false otherwise - * - * @since 2.1 - */ - public static boolean decodeToFile( String dataToDecode, String filename ) - { - boolean success = false; - Base64.OutputStream bos = null; - try - { - bos = new Base64.OutputStream( - new java.io.FileOutputStream( filename ), Base64.DECODE ); - bos.write( dataToDecode.getBytes( PREFERRED_ENCODING ) ); - success = true; - } // end try - catch( java.io.IOException e ) - { - success = false; - } // end catch: IOException - finally - { - try{ bos.close(); } catch( Exception e ){} - } // end finally - - return success; - } // end decodeToFile - - - - - /** - * Convenience method for reading a base64-encoded - * file and decoding it. - * - * @param filename Filename for reading encoded data - * @return decoded byte array or null if unsuccessful - * - * @since 2.1 - */ - public static byte[] decodeFromFile( String filename ) - { - byte[] decodedData = null; - Base64.InputStream bis = null; - try - { - // Set up some useful variables - java.io.File file = new java.io.File( filename ); - byte[] buffer = null; - int length = 0; - int numBytes = 0; - - // Check for size of file - if( file.length() > Integer.MAX_VALUE ) - { - logger.error( Logger.SECURITY, "File is too big for this convenience method (" + file.length() + " bytes)." ); - return null; - } // end if: file too big for int index - buffer = new byte[ (int)file.length() ]; - - // Open a stream - bis = new Base64.InputStream( - new java.io.BufferedInputStream( - new java.io.FileInputStream( file ) ), Base64.DECODE ); - - // Read until done - while( ( numBytes = bis.read( buffer, length, 4096 ) ) >= 0 ) - length += numBytes; - - // Save in a variable to return - decodedData = new byte[ length ]; - System.arraycopy( buffer, 0, decodedData, 0, length ); - - } // end try - catch( java.io.IOException e ) - { - logger.error( Logger.SECURITY, "Error decoding from file " + filename, e ); - } // end catch: IOException - finally - { - try{ bis.close(); } catch( Exception e) {} - } // end finally - - return decodedData; - } // end decodeFromFile - - - - /** - * Convenience method for reading a binary file - * and base64-encoding it. - * - * @param filename Filename for reading binary data - * @return base64-encoded string or null if unsuccessful - * - * @since 2.1 - */ - public static String encodeFromFile( String filename ) - { - String encodedData = null; - Base64.InputStream bis = null; - try - { - // Set up some useful variables - java.io.File file = new java.io.File( filename ); - byte[] buffer = new byte[ Math.max((int)(file.length() * 1.4),40) ]; // Need max() for math on small files (v2.2.1) - int length = 0; - int numBytes = 0; - - // Open a stream - bis = new Base64.InputStream( - new java.io.BufferedInputStream( - new java.io.FileInputStream( file ) ), Base64.ENCODE ); - - // Read until done - while( ( numBytes = bis.read( buffer, length, 4096 ) ) >= 0 ) - length += numBytes; - - // Save in a variable to return - encodedData = new String( buffer, 0, length, Base64.PREFERRED_ENCODING ); - - } // end try - catch( java.io.IOException e ) - { - logger.error( Logger.SECURITY, "Error encoding from file " + filename, e ); - } // end catch: IOException - finally - { - try{ bis.close(); } catch( Exception e) {} - } // end finally - - return encodedData; - } // end encodeFromFile - - - - - /** - * Reads infile and encodes it to outfile. - * - * @param infile Input file - * @param outfile Output file - * @return true if the operation is successful - * @since 2.2 - */ - public static boolean encodeFileToFile( String infile, String outfile ) - { - boolean success = false; - java.io.InputStream in = null; - java.io.OutputStream out = null; - try{ - in = new Base64.InputStream( - new java.io.BufferedInputStream( - new java.io.FileInputStream( infile ) ), - Base64.ENCODE ); - out = new java.io.BufferedOutputStream( new java.io.FileOutputStream( outfile ) ); - byte[] buffer = new byte[65536]; // 64K - int read = -1; - while( ( read = in.read(buffer) ) >= 0 ){ - out.write( buffer,0,read ); - } // end while: through file - success = true; - } catch( java.io.IOException exc ){ - logger.error( Logger.SECURITY, "Problem encoding file to file", exc ); - } finally{ - try{ in.close(); } catch( Exception exc ){} - try{ out.close(); } catch( Exception exc ){} - } // end finally - - return success; - } // end encodeFileToFile - - - - /** - * Reads infile and decodes it to outfile. - * - * @param infile Input file - * @param outfile Output file - * @return true if the operation is successful - * @since 2.2 - */ - public static boolean decodeFileToFile( String infile, String outfile ) - { - boolean success = false; - java.io.InputStream in = null; - java.io.OutputStream out = null; - try{ - in = new Base64.InputStream( - new java.io.BufferedInputStream( - new java.io.FileInputStream( infile ) ), - Base64.DECODE ); - out = new java.io.BufferedOutputStream( new java.io.FileOutputStream( outfile ) ); - byte[] buffer = new byte[65536]; // 64K - int read = -1; - while( ( read = in.read(buffer) ) >= 0 ){ - out.write( buffer,0,read ); - } // end while: through file - success = true; - } catch( java.io.IOException exc ){ - logger.error( Logger.SECURITY, "Problem decoding file to file", exc ); - } finally{ - try{ in.close(); } catch( Exception exc ){} - try{ out.close(); } catch( Exception exc ){} - } // end finally - - return success; - } // end decodeFileToFile - - - /* ******** I N N E R C L A S S I N P U T S T R E A M ******** */ - - - - /** - * A {@link Base64.InputStream} will read data from another - * java.io.InputStream, given in the constructor, - * and encode/decode to/from Base64 notation on the fly. - * - * @see Base64 - * @since 1.3 - */ - public static class InputStream extends java.io.FilterInputStream - { - private boolean encode; // Encoding or decoding - private int position; // Current position in the buffer - private byte[] buffer; // Small buffer holding converted data - private int bufferLength; // Length of buffer (3 or 4) - private int numSigBytes; // Number of meaningful bytes in the buffer - private int lineLength; - private boolean breakLines; // Break lines at less than 80 characters - private int options; // Record options used to create the stream. - private byte[] alphabet; // Local copies to avoid extra method calls - private byte[] decodabet; // Local copies to avoid extra method calls - - - /** - * Constructs a {@link Base64.InputStream} in DECODE mode. - * - * @param in the java.io.InputStream from which to read data. - * @since 1.3 - */ - public InputStream( java.io.InputStream in ) - { - this( in, DECODE ); - } // end constructor - - - /** - * Constructs a {@link Base64.InputStream} in - * either ENCODE or DECODE mode. - *

- * Valid options:

-         *   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 ) - * - * - * @param in the java.io.InputStream from which to read data. - * @param options Specified options - * @see Base64#ENCODE - * @see Base64#DECODE - * @see Base64#DONT_BREAK_LINES - * @since 2.0 - */ - public InputStream( java.io.InputStream in, int options ) - { - super( in ); - this.breakLines = (options & DONT_BREAK_LINES) != DONT_BREAK_LINES; - this.encode = (options & ENCODE) == ENCODE; - this.bufferLength = encode ? 4 : 3; - this.buffer = new byte[ bufferLength ]; - this.position = -1; - this.lineLength = 0; - this.options = options; // Record for later, mostly to determine which alphabet to use - this.alphabet = getAlphabet(options); - this.decodabet = getDecodabet(options); - } // end constructor - - /** - * Reads enough of the input stream to convert - * to/from Base64 and returns the next byte. - * - * @return next byte - * @since 1.3 - */ - public int read() throws java.io.IOException - { - // Do we need to get data? - if( position < 0 ) - { - if( encode ) - { - byte[] b3 = new byte[3]; - int numBinaryBytes = 0; - for( int i = 0; i < 3; i++ ) - { - try - { - int b = in.read(); - - // If end of stream, b is -1. - if( b >= 0 ) - { - b3[i] = (byte)b; - numBinaryBytes++; - } // end if: not end of stream - - } // end try: read - catch( java.io.IOException e ) - { - // Only a problem if we got no data at all. - if( i == 0 ) - throw e; - - } // end catch - } // end for: each needed input byte - - if( numBinaryBytes > 0 ) - { - encode3to4( b3, 0, numBinaryBytes, buffer, 0, options ); - position = 0; - numSigBytes = 4; - } // end if: got data - else - { - return -1; - } // end else - } // end if: encoding - - // Else decoding - else - { - byte[] b4 = new byte[4]; - int i = 0; - for( i = 0; i < 4; i++ ) - { - // Read four "meaningful" bytes: - int b = 0; - do{ b = in.read(); } - while( b >= 0 && decodabet[ b & 0x7f ] <= WHITE_SPACE_ENC ); - - if( b < 0 ) - break; // Reads a -1 if end of stream - - b4[i] = (byte)b; - } // end for: each needed input byte - - if( i == 4 ) - { - numSigBytes = decode4to3( b4, 0, buffer, 0, options ); - position = 0; - } // end if: got four characters - else if( i == 0 ){ - return -1; - } // end else if: also padded correctly - else - { - // Must have broken out from above. - throw new java.io.IOException( "Improperly padded Base64 input." ); - } // end - - } // end else: decode - } // end else: get data - - // Got data? - if( position >= 0 ) - { - // End of relevant data? - if( /*!encode &&*/ position >= numSigBytes ) - return -1; - - if( encode && breakLines && lineLength >= MAX_LINE_LENGTH ) - { - lineLength = 0; - return '\n'; - } // end if - else - { - lineLength++; // This isn't important when decoding - // but throwing an extra "if" seems - // just as wasteful. - - int b = buffer[ position++ ]; - - if( position >= bufferLength ) - position = -1; - - return b & 0xFF; // This is how you "cast" a byte that's - // intended to be unsigned. - } // end else - } // end if: position >= 0 - - // Else error - else - { - // When JDK1.4 is more accepted, use an assertion here. - throw new java.io.IOException( "Error in Base64 code reading stream." ); - } // end else - } // end read - - - /** - * Calls {@link #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. - * - * @param dest array to hold values - * @param off offset for array - * @param len max number of bytes to read into array - * @return bytes read into array or -1 if end of stream is encountered. - * @since 1.3 - */ - public int read( byte[] dest, int off, int len ) throws java.io.IOException - { - int i; - int b; - for( i = 0; i < len; i++ ) - { - b = read(); - - //if( b < 0 && i == 0 ) - // return -1; - - if( b >= 0 ) - dest[off + i] = (byte)b; - else if( i == 0 ) - return -1; - else - break; // Out of 'for' loop - } // end for: each byte read - return i; - } // end read - - } // end inner class InputStream - - - - - - - /* ******** I N N E R C L A S S O U T P U T S T R E A M ******** */ - - - - /** - * A {@link Base64.OutputStream} will write data to another - * java.io.OutputStream, given in the constructor, - * and encode/decode to/from Base64 notation on the fly. - * - * @see Base64 - * @since 1.3 - */ - public static class OutputStream extends java.io.FilterOutputStream - { - private boolean encode; - private int position; - private byte[] buffer; - private int bufferLength; - private int lineLength; - private boolean breakLines; - private byte[] b4; // Scratch used in a few places - private boolean suspendEncoding; - private int options; // Record for later - private byte[] alphabet; // Local copies to avoid extra method calls - private byte[] decodabet; // Local copies to avoid extra method calls - - /** - * Constructs a {@link Base64.OutputStream} in ENCODE mode. - * - * @param out the java.io.OutputStream to which data will be written. - * @since 1.3 - */ - public OutputStream( java.io.OutputStream out ) - { - this( out, ENCODE ); - } // end constructor - - - /** - * Constructs a {@link Base64.OutputStream} in - * either ENCODE or DECODE mode. - *

- * Valid options:

-         *   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 ) - * - * @param out the java.io.OutputStream to which data will be written. - * @param options Specified options. - * @see Base64#ENCODE - * @see Base64#DECODE - * @see Base64#DONT_BREAK_LINES - * @since 1.3 - */ - public OutputStream( java.io.OutputStream out, int options ) - { - super( out ); - this.breakLines = (options & DONT_BREAK_LINES) != DONT_BREAK_LINES; - this.encode = (options & ENCODE) == ENCODE; - this.bufferLength = encode ? 3 : 4; - this.buffer = new byte[ bufferLength ]; - this.position = 0; - this.lineLength = 0; - this.suspendEncoding = false; - this.b4 = new byte[4]; - this.options = options; - this.alphabet = getAlphabet(options); - this.decodabet = getDecodabet(options); - } // end constructor - - - /** - * 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. - * - * @param theByte the byte to write - * @since 1.3 - */ - public void write(int theByte) throws java.io.IOException - { - // Encoding suspended? - if( suspendEncoding ) - { - super.out.write( theByte ); - return; - } // end if: supsended - - // Encode? - if( encode ) - { - buffer[ position++ ] = (byte)theByte; - if( position >= bufferLength ) // Enough to encode. - { - out.write( encode3to4( b4, buffer, bufferLength, options ) ); - - lineLength += 4; - if( breakLines && lineLength >= MAX_LINE_LENGTH ) - { - out.write( NEW_LINE ); - lineLength = 0; - } // end if: end of line - - position = 0; - } // end if: enough to output - } // end if: encoding - - // Else, Decoding - else - { - // Meaningful Base64 character? - if( decodabet[ theByte & 0x7f ] > WHITE_SPACE_ENC ) - { - buffer[ position++ ] = (byte)theByte; - if( position >= bufferLength ) // Enough to output. - { - int len = Base64.decode4to3( buffer, 0, b4, 0, options ); - out.write( b4, 0, len ); - //out.write( Base64.decode4to3( buffer ) ); - position = 0; - } // end if: enough to output - } // end if: meaningful base64 character - else if( decodabet[ theByte & 0x7f ] != WHITE_SPACE_ENC ) - { - throw new java.io.IOException( "Invalid character in Base64 data." ); - } // end else: not white space either - } // end else: decoding - } // end write - - - - /** - * Calls {@link #write(int)} repeatedly until len - * bytes are written. - * - * @param theBytes array from which to read bytes - * @param off offset for array - * @param len max number of bytes to read into array - * @since 1.3 - */ - public void write( byte[] theBytes, int off, int len ) throws java.io.IOException - { - // Encoding suspended? - if( suspendEncoding ) - { - super.out.write( theBytes, off, len ); - return; - } // end if: supsended - - for( int i = 0; i < len; i++ ) - { - write( theBytes[ off + i ] ); - } // end for: each byte written - - } // end write - - - - /** - * Method added by PHIL. [Thanks, PHIL. -Rob] - * This pads the buffer without closing the stream. - */ - public void flushBase64() throws java.io.IOException - { - if( position > 0 ) - { - if( encode ) - { - out.write( encode3to4( b4, buffer, position, options ) ); - position = 0; - } // end if: encoding - else - { - throw new java.io.IOException( "Base64 input not properly padded." ); - } // end else: decoding - } // end if: buffer partially full - - } // end flush - - - /** - * Flushes and closes (I think, in the superclass) the stream. - * - * @since 1.3 - */ - public void close() throws java.io.IOException - { - // 1. Ensure that pending characters are written - flushBase64(); - - // 2. Actually close the stream - // Base class both flushes and closes. - super.close(); - - buffer = null; - out = null; - } // end close - - - - /** - * Suspends encoding of the stream. - * May be helpful if you need to embed a piece of - * base640-encoded data in a stream. - * - * @since 1.5.1 - */ - public void suspendEncoding() throws java.io.IOException - { - flushBase64(); - this.suspendEncoding = true; - } // end suspendEncoding - - - /** - * Resumes encoding of the stream. - * May be helpful if you need to embed a piece of - * base640-encoded data in a stream. - * - * @since 1.5.1 - */ - public void resumeEncoding() - { - this.suspendEncoding = false; - } // end resumeEncoding - - - - } // end inner class OutputStream - - -} // end class Base64 +package org.owasp.esapi.codecs; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Logger; + +// CHECKME: Version at http://iharder.net/base64 is up to v2.3.3. Some semantic changes +// starting with v2.3. Should we upgrade and then add ESAPI logging or stay at 2.2.2 base? +// I think that really depends on how much OWASP ESAPI plans on tracking changes to this +// version vs. if the plan was just to fork from it and maintain OWASP's own version. +// At this point, I think I prefer split from tracking Harder's original, but I'm easily +// persuaded otherwise. (In fact, we have already done so w/ decodeToObject().) - Kevin Wall + +/** + *

Encodes and decodes to and from Base64 notation.

+ *

Homepage: http://iharder.net/base64 + * (based on version 2.2.2).

+ * + *

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:

+ * + * String encoded = Base64.encodeBytes( mybytes, Base64.GZIP | Base64.DONT_BREAK_LINES ); + * + *

to compress the data before encoding it and then making the output have no newline characters.

+ * + * + *

+ * Original 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: + *
      + *
    1. The default is RFC3548 format.
    2. + *
    3. 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
    4. + *
    5. 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
    6. + *
    + * 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 passes 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. + *

+ * + * @author Robert Harder + * @author rob@iharder.net + * @version 2.2.2 + */ +public class Base64 +{ + +/* ******** P U B L I C F I E L D S ******** */ + + + /** No options specified. Value is zero. */ + public final static int NO_OPTIONS = 0; + + /** Specify encoding. */ + public final static int ENCODE = 1; + + /** Specify decoding. */ + public final static int DECODE = 0; + + /** Specify that data should be gzip-compressed. */ + public final static int GZIP = 2; + + /** Don't break lines when encoding (violates strict Base64 specification) */ + public final static int DONT_BREAK_LINES = 8; + + /** + * 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 final static int URL_SAFE = 16; + + /** + * Encode using the special "ordered" dialect of Base64 described here: + * http://www.faqs.org/qa/rfcc-1940.html. + */ + public final static int ORDERED = 32; + + /** + * System property name that must be set to true in order to invoke {@code Base64.decodeToObject()}. + * @link https://github.com/ESAPI/esapi-java-legacy/issues/354 + * @link http://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/ + */ + public final static String ENABLE_UNSAFE_SERIALIZATION = "org.owasp.esapi.enableUnsafeSerialization"; // Do NOT change! + +/* ******** P R I V A T E F I E L D S ******** */ + + /** Maximum line length (76) of Base64 output. */ + private final static int MAX_LINE_LENGTH = 76; + + /** The equals sign (=) as a byte. */ + private final static byte EQUALS_SIGN = (byte)'='; + + /** The new line character (\n) as a byte. */ + private final static byte NEW_LINE = (byte)'\n'; + + /** Preferred encoding. */ + private final static String PREFERRED_ENCODING = "UTF-8"; + + /** End of line character. */ + private final static String EOL = System.getProperty("line.separator", "\n"); + + + // I think I end up not using the BAD_ENCODING indicator. + //private final static byte BAD_ENCODING = -9; // Indicates error in encoding + private final static byte WHITE_SPACE_ENC = -5; // Indicates white space in encoding + private final static byte EQUALS_SIGN_ENC = -1; // Indicates equals sign in encoding + + private static final Logger logger = ESAPI.getLogger("Base64"); + +/* ******** S T A N D A R D B A S E 6 4 A L P H A B E T ******** */ + + /** The 64 valid Base64 values. */ + //private final static byte[] ALPHABET; + /* Host platform me be something funny like EBCDIC, so we hard code these values. */ + private final static byte[] _STANDARD_ALPHABET = + { + (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', + (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', + (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', + (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', + (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', + (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', + (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', + (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z', + (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', + (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'+', (byte)'/' + }; + + /** + * Translates a Base64 value to either its 6-bit reconstruction value + * or a negative number indicating some other meaning. + **/ + private final static byte[] _STANDARD_DECODABET = + { + -9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 0 - 8 + -5,-5, // Whitespace: Tab and Linefeed + -9,-9, // Decimal 11 - 12 + -5, // Whitespace: Carriage Return + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 14 - 26 + -9,-9,-9,-9,-9, // Decimal 27 - 31 + -5, // Whitespace: Space + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 33 - 42 + 62, // Plus sign at decimal 43 + -9,-9,-9, // Decimal 44 - 46 + 63, // Slash at decimal 47 + 52,53,54,55,56,57,58,59,60,61, // Numbers zero through nine + -9,-9,-9, // Decimal 58 - 60 + -1, // Equals sign at decimal 61 + -9,-9,-9, // Decimal 62 - 64 + 0,1,2,3,4,5,6,7,8,9,10,11,12,13, // Letters 'A' through 'N' + 14,15,16,17,18,19,20,21,22,23,24,25, // Letters 'O' through 'Z' + -9,-9,-9,-9,-9,-9, // Decimal 91 - 96 + 26,27,28,29,30,31,32,33,34,35,36,37,38, // Letters 'a' through 'm' + 39,40,41,42,43,44,45,46,47,48,49,50,51, // Letters 'n' through 'z' + -9,-9,-9,-9 // Decimal 123 - 126 + /*,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 127 - 139 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */ + }; + + +/* ******** U R L S A F E B A S E 6 4 A L P H A B E T ******** */ + + /** + * Used in the URL- and Filename-safe dialect described in Section 4 of RFC3548: + * http://www.faqs.org/rfcs/rfc3548.html. + * Notice that the last two bytes become "hyphen" and "underscore" instead of "plus" and "slash." + */ + private final static byte[] _URL_SAFE_ALPHABET = + { + (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', + (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', + (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', + (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', + (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', + (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', + (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', + (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z', + (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', + (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'-', (byte)'_' + }; + + /** + * Used in decoding URL- and Filename-safe dialects of Base64. + */ + private final static byte[] _URL_SAFE_DECODABET = + { + -9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 0 - 8 + -5,-5, // Whitespace: Tab and Linefeed + -9,-9, // Decimal 11 - 12 + -5, // Whitespace: Carriage Return + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 14 - 26 + -9,-9,-9,-9,-9, // Decimal 27 - 31 + -5, // Whitespace: Space + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 33 - 42 + -9, // Plus sign at decimal 43 + -9, // Decimal 44 + 62, // Minus sign at decimal 45 + -9, // Decimal 46 + -9, // Slash at decimal 47 + 52,53,54,55,56,57,58,59,60,61, // Numbers zero through nine + -9,-9,-9, // Decimal 58 - 60 + -1, // Equals sign at decimal 61 + -9,-9,-9, // Decimal 62 - 64 + 0,1,2,3,4,5,6,7,8,9,10,11,12,13, // Letters 'A' through 'N' + 14,15,16,17,18,19,20,21,22,23,24,25, // Letters 'O' through 'Z' + -9,-9,-9,-9, // Decimal 91 - 94 + 63, // Underscore at decimal 95 + -9, // Decimal 96 + 26,27,28,29,30,31,32,33,34,35,36,37,38, // Letters 'a' through 'm' + 39,40,41,42,43,44,45,46,47,48,49,50,51, // Letters 'n' through 'z' + -9,-9,-9,-9 // Decimal 123 - 126 + /*,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 127 - 139 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */ + }; + + + +/* ******** O R D E R E D B A S E 6 4 A L P H A B E T ******** */ + + /** + * I don't get the point of this technique, but it is described here: + * http://www.faqs.org/qa/rfcc-1940.html. + */ + private final static byte[] _ORDERED_ALPHABET = + { + (byte)'-', + (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', + (byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9', + (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', + (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', + (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', + (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', + (byte)'_', + (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', + (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', + (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', + (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z' + }; + + /** + * Used in decoding the "ordered" dialect of Base64. + */ + private final static byte[] _ORDERED_DECODABET = + { + -9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 0 - 8 + -5,-5, // Whitespace: Tab and Linefeed + -9,-9, // Decimal 11 - 12 + -5, // Whitespace: Carriage Return + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 14 - 26 + -9,-9,-9,-9,-9, // Decimal 27 - 31 + -5, // Whitespace: Space + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 33 - 42 + -9, // Plus sign at decimal 43 + -9, // Decimal 44 + 0, // Minus sign at decimal 45 + -9, // Decimal 46 + -9, // Slash at decimal 47 + 1,2,3,4,5,6,7,8,9,10, // Numbers zero through nine + -9,-9,-9, // Decimal 58 - 60 + -1, // Equals sign at decimal 61 + -9,-9,-9, // Decimal 62 - 64 + 11,12,13,14,15,16,17,18,19,20,21,22,23, // Letters 'A' through 'M' + 24,25,26,27,28,29,30,31,32,33,34,35,36, // Letters 'N' through 'Z' + -9,-9,-9,-9, // Decimal 91 - 94 + 37, // Underscore at decimal 95 + -9, // Decimal 96 + 38,39,40,41,42,43,44,45,46,47,48,49,50, // Letters 'a' through 'm' + 51,52,53,54,55,56,57,58,59,60,61,62,63, // Letters 'n' through 'z' + -9,-9,-9,-9 // Decimal 123 - 126 + /*,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 127 - 139 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */ + }; + + +/* ******** D E T E R M I N E W H I C H A L H A B E T ******** */ + + + /** + * Returns one of the _SOMETHING_ALPHABET byte arrays depending on + * the options specified. + * It's possible, though silly, to specify ORDERED and URLSAFE + * in which case one of them will be picked, though there is + * no guarantee as to which one will be picked. + */ + private final static byte[] getAlphabet( int options ) + { + if( (options & URL_SAFE) == URL_SAFE ) return _URL_SAFE_ALPHABET; + else if( (options & ORDERED) == ORDERED ) return _ORDERED_ALPHABET; + else return _STANDARD_ALPHABET; + + } // end getAlphabet + + + /** + * Returns one of the _SOMETHING_DECODABET byte arrays depending on + * the options specified. + * It's possible, though silly, to specify ORDERED and URL_SAFE + * in which case one of them will be picked, though there is + * no guarantee as to which one will be picked. + */ + private final static byte[] getDecodabet( int options ) + { + if( (options & URL_SAFE) == URL_SAFE ) return _URL_SAFE_DECODABET; + else if( (options & ORDERED) == ORDERED ) return _ORDERED_DECODABET; + else return _STANDARD_DECODABET; + + } // end getDecodaabet + + /** Defeats instantiation. */ + private Base64(){} + + /** + * 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. + * @param args + */ + public final static void main( String[] args ) + { + if( args.length < 3 ){ + usage("Not enough arguments."); + } // end if: args.length < 3 + else { + String flag = args[0]; + String infile = args[1]; + String outfile = args[2]; + if( flag.equals( "-e" ) ){ + Base64.encodeFileToFile( infile, outfile ); + } // end if: encode + else if( flag.equals( "-d" ) ) { + Base64.decodeFileToFile( infile, outfile ); + } // end else if: decode + else { + usage( "Unknown flag: " + flag ); + } // end else + } // end else + } // end main + + /** + * Prints command line usage. + * + * @param msg A message to include with usage info. + */ + private final static void usage( String msg ) + { + System.err.println( msg ); + System.err.println( "Usage: java Base64 -e|-d inputfile outputfile" ); + } // end usage + +/* ******** E N C O D I N G M E T H O D S ******** */ + + /** + * Encodes up to the first three bytes of array threeBytes + * and returns a four-byte array in Base64 notation. + * The actual number of significant bytes in your array is + * given by numSigBytes. + * The array threeBytes needs only be as big as + * numSigBytes. + * Code can reuse a byte array by passing a four-byte array as b4. + * + * @param b4 A reusable byte array to reduce array instantiation + * @param threeBytes the array to convert + * @param numSigBytes the number of significant bytes in your array + * @return four byte array in Base64 notation. + * @since 1.5.1 + */ + private static byte[] encode3to4( byte[] b4, byte[] threeBytes, int numSigBytes, int options ) + { + encode3to4( threeBytes, 0, numSigBytes, b4, 0, options ); + return b4; + } // end encode3to4 + + /** + *

Encodes up to three bytes of the array source + * and writes the resulting four Base64 bytes to destination. + * The source and destination arrays can be manipulated + * anywhere along their length by specifying + * srcOffset and destOffset. + * This method does not check to make sure your arrays + * are large enough to accomodate srcOffset + 3 for + * the source array or destOffset + 4 for + * the destination array. + * The actual number of significant bytes in your array is + * given by numSigBytes.

+ *

This is the lowest level of the encoding methods with + * all possible parameters.

+ * + * @param source the array to convert + * @param srcOffset the index where conversion begins + * @param numSigBytes the number of significant bytes in your array + * @param destination the array to hold the conversion + * @param destOffset the index where output will be put + * @return the destination array + * @since 1.3 + */ + private static byte[] encode3to4( + byte[] source, int srcOffset, int numSigBytes, + byte[] destination, int destOffset, int options ) + { + byte[] ALPHABET = getAlphabet( options ); + + // 1 2 3 + // 01234567890123456789012345678901 Bit position + // --------000000001111111122222222 Array position from threeBytes + // --------| || || || | Six bit groups to index ALPHABET + // >>18 >>12 >> 6 >> 0 Right shift necessary + // 0x3f 0x3f 0x3f Additional AND + + // Create buffer with zero-padding if there are only one or two + // significant bytes passed in the array. + // We have to shift left 24 in order to flush out the 1's that appear + // when Java treats a value as negative that is cast from a byte to an int. + int inBuff = ( numSigBytes > 0 ? ((source[ srcOffset ] << 24) >>> 8) : 0 ) + | ( numSigBytes > 1 ? ((source[ srcOffset + 1 ] << 24) >>> 16) : 0 ) + | ( numSigBytes > 2 ? ((source[ srcOffset + 2 ] << 24) >>> 24) : 0 ); + + switch( numSigBytes ) + { + case 3: + destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ]; + destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ]; + destination[ destOffset + 2 ] = ALPHABET[ (inBuff >>> 6) & 0x3f ]; + destination[ destOffset + 3 ] = ALPHABET[ (inBuff ) & 0x3f ]; + return destination; + + case 2: + destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ]; + destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ]; + destination[ destOffset + 2 ] = ALPHABET[ (inBuff >>> 6) & 0x3f ]; + destination[ destOffset + 3 ] = EQUALS_SIGN; + return destination; + + case 1: + destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ]; + destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ]; + destination[ destOffset + 2 ] = EQUALS_SIGN; + destination[ destOffset + 3 ] = EQUALS_SIGN; + return destination; + + default: + return destination; + } // end switch + } // end encode3to4 + + /** + * Encodes a byte array into Base64 notation. + * Does not GZip-compress data. + * + * @param source The data to convert + * @return The Base64-encoded resulting string + * @since 1.4 + */ + public static String encodeBytes( byte[] source ) + { + return encodeBytes( source, 0, source.length, NO_OPTIONS ); + } // end encodeBytes + + + + /** + * 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 + *

+ * Example: encodeBytes( myData, Base64.GZIP | Base64.DONT_BREAK_LINES ) + * + * + * @param source The data to convert + * @param options Specified options + * @return The Base64-encoded resulting string + * @see Base64#GZIP + * @see Base64#DONT_BREAK_LINES + * @since 2.0 + */ + public static String encodeBytes( byte[] source, int options ) + { + return encodeBytes( source, 0, source.length, options ); + } // end encodeBytes + + /** + * Encodes a byte array into Base64 notation. + * Does not GZip-compress data. + * + * @param source The data to convert + * @param off Offset in array where conversion should begin + * @param len Length of data to convert + * @return The Base64-encoded resulting string + * @since 1.4 + */ + public static String encodeBytes( byte[] source, int off, int len ) + { + return encodeBytes( source, off, len, NO_OPTIONS ); + } // end encodeBytes + + /** + * 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 + *

+ * Example: encodeBytes( myData, Base64.GZIP | Base64.DONT_BREAK_LINES ) + * + * + * @param source The data to convert + * @param off Offset in array where conversion should begin + * @param len Length of data to convert + * @param options alphabet type is pulled from this (standard, url-safe, ordered) + * @return The Base64-encoded resulting string + * @see Base64#GZIP + * @see Base64#DONT_BREAK_LINES + * @since 2.0 + */ + public static String encodeBytes( byte[] source, int off, int len, int options ) + { + // Isolate options + int dontBreakLines = ( options & DONT_BREAK_LINES ); + int gzip = ( options & GZIP ); + + // Compress? + if( gzip == GZIP ) + { + java.io.ByteArrayOutputStream baos = null; + java.util.zip.GZIPOutputStream gzos = null; + Base64.OutputStream b64os = null; + + try + { + // GZip -> Base64 -> ByteArray + baos = new java.io.ByteArrayOutputStream(); + b64os = new Base64.OutputStream( baos, ENCODE | options ); + gzos = new java.util.zip.GZIPOutputStream( b64os ); + + gzos.write( source, off, len ); + gzos.close(); + } // end try + catch( java.io.IOException e ) + { + logger.error( Logger.SECURITY_FAILURE, "Problem writing gzip stream", e ); + return null; + } // end catch + finally + { + try{ gzos.close(); } catch( Exception e ){} + try{ b64os.close(); } catch( Exception e ){} + try{ baos.close(); } catch( Exception e ){} + } // end finally + + // Return value according to relevant encoding. + try + { + return new String( baos.toByteArray(), PREFERRED_ENCODING ); + } // end try + catch (java.io.UnsupportedEncodingException uue) + { + return new String( baos.toByteArray() ); + } // end catch + } // end if: compress + + // Else, don't compress. Better not to use streams at all then. + else + { + // Convert option to boolean in way that code likes it. + boolean breakLines = dontBreakLines == 0; + + int len43 = len * 4 / 3; + byte[] outBuff = new byte[ ( len43 ) // Main 4:3 + + ( (len % 3) > 0 ? 4 : 0 ) // Account for padding + + (breakLines ? ( len43 / MAX_LINE_LENGTH ) : 0) ]; // New lines + int d = 0; + int e = 0; + int len2 = len - 2; + int lineLength = 0; + for( ; d < len2; d+=3, e+=4 ) + { + encode3to4( source, d+off, 3, outBuff, e, options ); + + lineLength += 4; + if( breakLines && lineLength == MAX_LINE_LENGTH ) + { + outBuff[e+4] = NEW_LINE; + e++; + lineLength = 0; + } // end if: end of line + } // en dfor: each piece of array + + if( d < len ) + { + encode3to4( source, d+off, len - d, outBuff, e, options ); + e += 4; + } // end if: some padding needed + + + // Return value according to relevant encoding. + try + { + return new String( outBuff, 0, e, PREFERRED_ENCODING ); + } // end try + catch (java.io.UnsupportedEncodingException uue) + { + return new String( outBuff, 0, e ); + } // end catch + + } // end else: don't compress + + } // end encodeBytes + +/* ******** D E C O D I N G M E T H O D S ******** */ + + /** + * Decodes four bytes from array source + * and writes the resulting bytes (up to three of them) + * to destination. + * The source and destination arrays can be manipulated + * anywhere along their length by specifying + * srcOffset and destOffset. + * This method does not check to make sure your arrays + * are large enough to accomodate srcOffset + 4 for + * the source array or destOffset + 3 for + * the destination array. + * This method returns the actual number of bytes that + * were converted from the Base64 encoding. + *

This is the lowest level of the decoding methods with + * all possible parameters.

+ * + * + * @param source the array to convert + * @param srcOffset the index where conversion begins + * @param destination the array to hold the conversion + * @param destOffset the index where output will be put + * @param options alphabet type is pulled from this (standard, url-safe, ordered) + * @return the number of decoded bytes converted + * @since 1.3 + */ + private static int decode4to3( byte[] source, int srcOffset, byte[] destination, int destOffset, int options ) + { + byte[] DECODABET = getDecodabet( options ); + + // Example: Dk== + if( source[ srcOffset + 2] == EQUALS_SIGN ) + { + // Two ways to do the same thing. Don't know which way I like best. + //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) + // | ( ( DECODABET[ source[ srcOffset + 1] ] << 24 ) >>> 12 ); + int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 ) + | ( ( DECODABET[ source[ srcOffset + 1] ] & 0xFF ) << 12 ); + + destination[ destOffset ] = (byte)( outBuff >>> 16 ); + return 1; + } + + // Example: DkL= + else if( source[ srcOffset + 3 ] == EQUALS_SIGN ) + { + // Two ways to do the same thing. Don't know which way I like best. + //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) + // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 ) + // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 ); + int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 ) + | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 ) + | ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) << 6 ); + + destination[ destOffset ] = (byte)( outBuff >>> 16 ); + destination[ destOffset + 1 ] = (byte)( outBuff >>> 8 ); + return 2; + } + + // Example: DkLE + else + { + try{ + // Two ways to do the same thing. Don't know which way I like best. + //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) + // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 ) + // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 ) + // | ( ( DECODABET[ source[ srcOffset + 3 ] ] << 24 ) >>> 24 ); + int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 ) + | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 ) + | ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) << 6) + | ( ( DECODABET[ source[ srcOffset + 3 ] ] & 0xFF ) ); + + + destination[ destOffset ] = (byte)( outBuff >> 16 ); + destination[ destOffset + 1 ] = (byte)( outBuff >> 8 ); + destination[ destOffset + 2 ] = (byte)( outBuff ); + + return 3; + }catch( Exception e){ + + // Remove these after checking -- for context only. + // logger.error( Logger.SECURITY_FAILURE, "Problem writing object", e ); + // logger.error( Logger.SECURITY_FAILURE, ""+source[srcOffset]+ ": " + ( DECODABET[ source[ srcOffset ] ] ) ); + // logger.error( Logger.SECURITY_FAILURE, ""+source[srcOffset+1]+ ": " + ( DECODABET[ source[ srcOffset + 1 ] ] ) ); + // logger.error( Logger.SECURITY_FAILURE, ""+source[srcOffset+2]+ ": " + ( DECODABET[ source[ srcOffset + 2 ] ] ) ); + // logger.error( Logger.SECURITY_FAILURE, ""+source[srcOffset+3]+ ": " + ( DECODABET[ source[ srcOffset + 3 ] ] ) ); + + // CHECKME: I replaced the 5 separate logger.error() calls above with a single logger.error() call so they can't + // become interleaved with other log entries from other threads. Normally this would have placed log entries + // on separate lines, so I also added line terminators here as well. (Probably don't want it all on one single + // really long log entry, do we?) Anyhow, somebody should check the formatting to ensure that it's + // esthetically pleasing, etc. But this works for me. I'm also OK if you want to remove all the line terminators + // in which case the declaration for EOL should be removed as well. - Kevin Wall + + StringBuilder sb = new StringBuilder("Problem writing object:"); + sb.append(EOL); + sb.append( source[srcOffset] ).append(": ").append( ( DECODABET[ source[ srcOffset ] ] ) ).append(EOL); + sb.append( source[srcOffset+1] ).append(": ").append( ( DECODABET[ source[ srcOffset + 1 ] ] ) ).append(EOL); + sb.append( source[srcOffset+2] ).append(": ").append( ( DECODABET[ source[ srcOffset + 2 ] ] ) ).append(EOL); + sb.append( source[srcOffset+3] ).append(": ").append( ( DECODABET[ source[ srcOffset + 3 ] ] ) ).append(EOL); + + logger.error( Logger.SECURITY_FAILURE, sb.toString(), e ); + return -1; + } // end catch + } + } // end decodeToBytes + + /** + * 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. + * + * @param source The Base64 encoded data + * @param off The offset of where to begin decoding + * @param len The length of characters to decode + * @param options + * @return decoded data + * @since 1.3 + */ + public static byte[] decode( byte[] source, int off, int len, int options ) + { + byte[] DECODABET = getDecodabet( options ); + + int len34 = len * 3 / 4; + byte[] outBuff = new byte[ len34 ]; // Upper limit on size of output + int outBuffPosn = 0; + + byte[] b4 = new byte[4]; + int b4Posn = 0; + int i = 0; + byte sbiCrop = 0; + byte sbiDecode = 0; + for( i = off; i < off+len; i++ ) + { + sbiCrop = (byte)(source[i] & 0x7f); // Only the low seven bits + sbiDecode = DECODABET[ sbiCrop ]; + + if( sbiDecode >= WHITE_SPACE_ENC ) // White space, Equals sign or better + { + if( sbiDecode >= EQUALS_SIGN_ENC ) + { + b4[ b4Posn++ ] = sbiCrop; + if( b4Posn > 3 ) + { + outBuffPosn += decode4to3( b4, 0, outBuff, outBuffPosn, options ); + b4Posn = 0; + + // If that was the equals sign, break out of 'for' loop + if( sbiCrop == EQUALS_SIGN ) + break; + } // end if: quartet built + + } // end if: equals sign or better + + } // end if: white space, equals sign or better + else + { + logger.error( Logger.SECURITY_FAILURE, "Bad Base64 input character at " + i + ": " + source[i] + "(decimal)" ); + return null; + } // end else: + } // each input character + + byte[] out = new byte[ outBuffPosn ]; + System.arraycopy( outBuff, 0, out, 0, outBuffPosn ); + return out; + } // end decode + + /** + * Decodes data from Base64 notation, automatically + * detecting gzip-compressed data and decompressing it. + * + * @param s the string to decode + * @return the decoded data + * @since 1.4 + */ + public static byte[] decode( String s ) + { + return decode( s, NO_OPTIONS ); + } + + /** + * Decodes data from Base64 notation, automatically + * detecting gzip-compressed data and decompressing it. + * + * @param s the string to decode + * @param options encode options such as URL_SAFE + * @return the decoded data + * @since 1.4 + */ + public static byte[] decode( String s, int options ) + { + byte[] bytes; + try + { + bytes = s.getBytes( PREFERRED_ENCODING ); + } + catch( java.io.UnsupportedEncodingException uee ) + { + bytes = s.getBytes(); // Uses native encoding + // CHECKME: Is this correct? I think it should be a warning instead of an error since nothing + // is re-thrown. I do think that *some* sort of logging is in order here especially since UTF-8 should + // always be available on all platforms. If it's not, then all bets are off on your runtime env. - Kevin Wall + logger.warning( Logger.SECURITY_FAILURE, "Problem decoding string using " + + PREFERRED_ENCODING + "; substituting native platform encoding instead", uee ); + } + + // Decode + bytes = decode( bytes, 0, bytes.length, options ); + + // Check to see if it's gzip-compressed + // GZIP Magic Two-Byte Number: 0x8b1f (35615) + if( bytes != null && bytes.length >= 4 ) + { + + int head = ((int)bytes[0] & 0xff) | ((bytes[1] << 8) & 0xff00); + if ( java.util.zip.GZIPInputStream.GZIP_MAGIC == head ) + { + java.io.ByteArrayInputStream bais = null; + java.util.zip.GZIPInputStream gzis = null; + java.io.ByteArrayOutputStream baos = null; + byte[] buffer = new byte[2048]; + int length = 0; + + try + { + baos = new java.io.ByteArrayOutputStream(); + bais = new java.io.ByteArrayInputStream( bytes ); + gzis = new java.util.zip.GZIPInputStream( bais ); + + while( ( length = gzis.read( buffer ) ) >= 0 ) + { + baos.write(buffer,0,length); + } // end while: reading input + + // No error? Get new bytes. + bytes = baos.toByteArray(); + + } // end try + catch( java.io.IOException e ) + { + // Just return originally-decoded bytes + } // end catch + finally + { + try{ baos.close(); } catch( Exception e ){} + try{ gzis.close(); } catch( Exception e ){} + try{ bais.close(); } catch( Exception e ){} + } // end finally + + } // end if: gzipped + } // end if: bytes.length >= 2 + + return bytes; + } // end decode + + /** + * Convenience method for encoding data to a file. + * + * @param dataToEncode byte array of data to encode in base64 form + * @param filename Filename for saving encoded data + * @return true if successful, false otherwise + * + * @since 2.1 + */ + public static boolean encodeToFile( byte[] dataToEncode, String filename ) + { + boolean success = false; + Base64.OutputStream bos = null; + try + { + bos = new Base64.OutputStream( + new java.io.FileOutputStream( filename ), Base64.ENCODE ); + bos.write( dataToEncode ); + success = true; + } // end try + catch( java.io.IOException e ) + { + + success = false; + } // end catch: IOException + finally + { + try{ bos.close(); } catch( Exception e ){} + } // end finally + + return success; + } // end encodeToFile + + /** + * Convenience method for decoding data to a file. + * + * @param dataToDecode Base64-encoded data as a string + * @param filename Filename for saving decoded data + * @return true if successful, false otherwise + * + * @since 2.1 + */ + public static boolean decodeToFile( String dataToDecode, String filename ) + { + boolean success = false; + Base64.OutputStream bos = null; + try + { + bos = new Base64.OutputStream( + new java.io.FileOutputStream( filename ), Base64.DECODE ); + bos.write( dataToDecode.getBytes( PREFERRED_ENCODING ) ); + success = true; + } // end try + catch( java.io.IOException e ) + { + success = false; + } // end catch: IOException + finally + { + try{ bos.close(); } catch( Exception e ){} + } // end finally + + return success; + } // end decodeToFile + + /** + * Convenience method for reading a base64-encoded + * file and decoding it. + * + * @param filename Filename for reading encoded data + * @return decoded byte array or null if unsuccessful + * + * @since 2.1 + */ + public static byte[] decodeFromFile( String filename ) + { + byte[] decodedData = null; + Base64.InputStream bis = null; + try + { + // Set up some useful variables + java.io.File file = new java.io.File( filename ); + byte[] buffer = null; + int length = 0; + int numBytes = 0; + + // Check for size of file + if( file.length() > Integer.MAX_VALUE ) + { + logger.error( Logger.SECURITY_FAILURE, "File is too big for this convenience method (" + file.length() + " bytes)." ); + return null; + } // end if: file too big for int index + buffer = new byte[ (int)file.length() ]; + + // Open a stream + bis = new Base64.InputStream( + new java.io.BufferedInputStream( + new java.io.FileInputStream( file ) ), Base64.DECODE ); + + // Read until done + while( ( numBytes = bis.read( buffer, length, 4096 ) ) >= 0 ) + length += numBytes; + + // Save in a variable to return + decodedData = new byte[ length ]; + System.arraycopy( buffer, 0, decodedData, 0, length ); + + } // end try + catch( java.io.IOException e ) + { + logger.error( Logger.SECURITY_FAILURE, "Error decoding from file " + filename, e ); + } // end catch: IOException + finally + { + try{ if (bis != null ) bis.close(); } catch( Exception e) {} + } // end finally + + return decodedData; + } // end decodeFromFile + + /** + * Convenience method for reading a binary file + * and base64-encoding it. + * + * @param filename Filename for reading binary data + * @return base64-encoded string or null if unsuccessful + * + * @since 2.1 + */ + public static String encodeFromFile( String filename ) + { + String encodedData = null; + Base64.InputStream bis = null; + try + { + // Set up some useful variables + java.io.File file = new java.io.File( filename ); + byte[] buffer = new byte[ Math.max((int)(file.length() * 1.4),40) ]; // Need max() for math on small files (v2.2.1) + int length = 0; + int numBytes = 0; + + // Open a stream + bis = new Base64.InputStream( + new java.io.BufferedInputStream( + new java.io.FileInputStream( file ) ), Base64.ENCODE ); + + // Read until done + while( ( numBytes = bis.read( buffer, length, 4096 ) ) >= 0 ) + length += numBytes; + + // Save in a variable to return + encodedData = new String( buffer, 0, length, Base64.PREFERRED_ENCODING ); + + } // end try + catch( java.io.IOException e ) + { + logger.error( Logger.SECURITY_FAILURE, "Error encoding from file " + filename, e ); + } // end catch: IOException + finally + { + try{ bis.close(); } catch( Exception e) {} + } // end finally + + return encodedData; + } // end encodeFromFile + + /** + * Reads infile and encodes it to outfile. + * + * @param infile Input file + * @param outfile Output file + * @return true if the operation is successful + * @since 2.2 + */ + public static boolean encodeFileToFile( String infile, String outfile ) + { + boolean success = false; + java.io.InputStream in = null; + java.io.OutputStream out = null; + try{ + in = new Base64.InputStream( + new java.io.BufferedInputStream( + new java.io.FileInputStream( infile ) ), + Base64.ENCODE ); + out = new java.io.BufferedOutputStream( new java.io.FileOutputStream( outfile ) ); + byte[] buffer = new byte[65536]; // 64K + int read = -1; + while( ( read = in.read(buffer) ) >= 0 ){ + out.write( buffer,0,read ); + } // end while: through file + success = true; + } catch( java.io.IOException exc ){ + logger.error( Logger.SECURITY_FAILURE, "Problem encoding file to file", exc ); + } finally{ + try{ in.close(); } catch( Exception exc ){} + try{ out.close(); } catch( Exception exc ){} + } // end finally + + return success; + } // end encodeFileToFile + + /** + * Reads infile and decodes it to outfile. + * + * @param infile Input file + * @param outfile Output file + * @return true if the operation is successful + * @since 2.2 + */ + public static boolean decodeFileToFile( String infile, String outfile ) + { + boolean success = false; + java.io.InputStream in = null; + java.io.OutputStream out = null; + try{ + in = new Base64.InputStream( + new java.io.BufferedInputStream( + new java.io.FileInputStream( infile ) ), + Base64.DECODE ); + out = new java.io.BufferedOutputStream( new java.io.FileOutputStream( outfile ) ); + byte[] buffer = new byte[65536]; // 64K + int read = -1; + while( ( read = in.read(buffer) ) >= 0 ){ + out.write( buffer,0,read ); + } // end while: through file + success = true; + } catch( java.io.IOException exc ){ + logger.error( Logger.SECURITY_FAILURE, "Problem decoding file to file", exc ); + } finally{ + try{ in.close(); } catch( Exception exc ){} + try{ out.close(); } catch( Exception exc ){} + } // end finally + + return success; + } // end decodeFileToFile + + /* ******** I N N E R C L A S S I N P U T S T R E A M ******** */ + + /** + * A {@link Base64.InputStream} will read data from another + * java.io.InputStream, given in the constructor, + * and encode/decode to/from Base64 notation on the fly. + * + * @see Base64 + * @since 1.3 + */ + public static class InputStream extends java.io.FilterInputStream + { + private boolean encode; // Encoding or decoding + private int position; // Current position in the buffer + private byte[] buffer; // Small buffer holding converted data + private int bufferLength; // Length of buffer (3 or 4) + private int numSigBytes; // Number of meaningful bytes in the buffer + private int lineLength; + private boolean breakLines; // Break lines at less than 80 characters + private int options; // Record options used to create the stream. + private byte[] decodabet; // Local copies to avoid extra method calls + + /** + * Constructs a {@link Base64.InputStream} in DECODE mode. + * + * @param in the java.io.InputStream from which to read data. + * @since 1.3 + */ + public InputStream( java.io.InputStream in ) + { + this( in, DECODE ); + } // end constructor + + /** + * Constructs a {@link Base64.InputStream} in + * either ENCODE or DECODE mode. + *

+ * Valid options:

+         *   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 ) + * + * + * @param in the java.io.InputStream from which to read data. + * @param options Specified options + * @see Base64#ENCODE + * @see Base64#DECODE + * @see Base64#DONT_BREAK_LINES + * @since 2.0 + */ + public InputStream( java.io.InputStream in, int options ) + { + super( in ); + this.breakLines = (options & DONT_BREAK_LINES) != DONT_BREAK_LINES; + this.encode = (options & ENCODE) == ENCODE; + this.bufferLength = encode ? 4 : 3; + this.buffer = new byte[ bufferLength ]; + this.position = -1; + this.lineLength = 0; + this.options = options; // Record for later, mostly to determine which alphabet to use + this.decodabet = getDecodabet(options); + } // end constructor + + /** + * Reads enough of the input stream to convert + * to/from Base64 and returns the next byte. + * + * @return next byte + * @throws java.io.IOException + * @since 1.3 + */ + public int read() throws java.io.IOException + { + // Do we need to get data? + if( position < 0 ) + { + if( encode ) + { + byte[] b3 = new byte[3]; + int numBinaryBytes = 0; + for( int i = 0; i < 3; i++ ) + { + try + { + int b = in.read(); + + // If end of stream, b is -1. + if( b >= 0 ) + { + b3[i] = (byte)b; + numBinaryBytes++; + } // end if: not end of stream + + } // end try: read + catch( java.io.IOException e ) + { + // Only a problem if we got no data at all. + if( i == 0 ) + throw e; + + } // end catch + } // end for: each needed input byte + + if( numBinaryBytes > 0 ) + { + encode3to4( b3, 0, numBinaryBytes, buffer, 0, options ); + position = 0; + numSigBytes = 4; + } // end if: got data + else + { + return -1; + } // end else + } // end if: encoding + + // Else decoding + else + { + byte[] b4 = new byte[4]; + int i = 0; + for( i = 0; i < 4; i++ ) + { + // Read four "meaningful" bytes: + int b = 0; + do{ b = in.read(); } + while( b >= 0 && decodabet[ b & 0x7f ] <= WHITE_SPACE_ENC ); + + if( b < 0 ) + break; // Reads a -1 if end of stream + + b4[i] = (byte)b; + } // end for: each needed input byte + + if( i == 4 ) + { + numSigBytes = decode4to3( b4, 0, buffer, 0, options ); + position = 0; + } // end if: got four characters + else if( i == 0 ){ + return -1; + } // end else if: also padded correctly + else + { + // Must have broken out from above. + throw new java.io.IOException( "Improperly padded Base64 input." ); + } // end + + } // end else: decode + } // end else: get data + + // Got data? + if( position >= 0 ) + { + // End of relevant data? + if( /*!encode &&*/ position >= numSigBytes ) + return -1; + + if( encode && breakLines && lineLength >= MAX_LINE_LENGTH ) + { + lineLength = 0; + return '\n'; + } // end if + else + { + lineLength++; // This isn't important when decoding + // but throwing an extra "if" seems + // just as wasteful. + + int b = buffer[ position++ ]; + + if( position >= bufferLength ) + position = -1; + + return b & 0xFF; // This is how you "cast" a byte that's + // intended to be unsigned. + } // end else + } // end if: position >= 0 + + // Else error + else + { + // When JDK1.4 is more accepted, use an assertion here. + throw new java.io.IOException( "Error in Base64 code reading stream." ); + } // end else + } // end read + + /** + * Calls {@link #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. + * + * @param dest array to hold values + * @param off offset for array + * @param len max number of bytes to read into array + * @return bytes read into array or -1 if end of stream is encountered. + * @throws java.io.IOException + * @since 1.3 + */ + public int read( byte[] dest, int off, int len ) throws java.io.IOException + { + int i; + int b; + for( i = 0; i < len; i++ ) + { + b = read(); + + //if( b < 0 && i == 0 ) + // return -1; + + if( b >= 0 ) + dest[off + i] = (byte)b; + else if( i == 0 ) + return -1; + else + break; // Out of 'for' loop + } // end for: each byte read + return i; + } // end read + + } // end inner class InputStream + + + /* ******** I N N E R C L A S S O U T P U T S T R E A M ******** */ + + /** + * A {@link Base64.OutputStream} will write data to another + * java.io.OutputStream, given in the constructor, + * and encode/decode to/from Base64 notation on the fly. + * + * @see Base64 + * @since 1.3 + */ + public static class OutputStream extends java.io.FilterOutputStream + { + private boolean encode; + private int position; + private byte[] buffer; + private int bufferLength; + private int lineLength; + private boolean breakLines; + private byte[] b4; // Scratch used in a few places + private boolean suspendEncoding; + private int options; // Record for later + private byte[] decodabet; // Local copies to avoid extra method calls + + /** + * Constructs a {@link Base64.OutputStream} in ENCODE mode. + * + * @param out the java.io.OutputStream to which data will be written. + * @since 1.3 + */ + public OutputStream( java.io.OutputStream out ) + { + this( out, ENCODE ); + } // end constructor + + /** + * Constructs a {@link Base64.OutputStream} in + * either ENCODE or DECODE mode. + *

+ * Valid options:

+         *   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 ) + * + * @param out the java.io.OutputStream to which data will be written. + * @param options Specified options. + * @see Base64#ENCODE + * @see Base64#DECODE + * @see Base64#DONT_BREAK_LINES + * @since 1.3 + */ + public OutputStream( java.io.OutputStream out, int options ) + { + super( out ); + this.breakLines = (options & DONT_BREAK_LINES) != DONT_BREAK_LINES; + this.encode = (options & ENCODE) == ENCODE; + this.bufferLength = encode ? 3 : 4; + this.buffer = new byte[ bufferLength ]; + this.position = 0; + this.lineLength = 0; + this.suspendEncoding = false; + this.b4 = new byte[4]; + this.options = options; + this.decodabet = getDecodabet(options); + } // end constructor + + /** + * 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. + * + * @param theByte the byte to write + * @throws java.io.IOException + * @since 1.3 + */ + public void write(int theByte) throws java.io.IOException + { + // Encoding suspended? + if( suspendEncoding ) + { + super.out.write( theByte ); + return; + } // end if: supsended + + // Encode? + if( encode ) + { + buffer[ position++ ] = (byte)theByte; + if( position >= bufferLength ) // Enough to encode. + { + out.write( encode3to4( b4, buffer, bufferLength, options ) ); + + lineLength += 4; + if( breakLines && lineLength >= MAX_LINE_LENGTH ) + { + out.write( NEW_LINE ); + lineLength = 0; + } // end if: end of line + + position = 0; + } // end if: enough to output + } // end if: encoding + + // Else, Decoding + else + { + // Meaningful Base64 character? + if( decodabet[ theByte & 0x7f ] > WHITE_SPACE_ENC ) + { + buffer[ position++ ] = (byte)theByte; + if( position >= bufferLength ) // Enough to output. + { + int len = Base64.decode4to3( buffer, 0, b4, 0, options ); + out.write( b4, 0, len ); + //out.write( Base64.decode4to3( buffer ) ); + position = 0; + } // end if: enough to output + } // end if: meaningful base64 character + else if( decodabet[ theByte & 0x7f ] != WHITE_SPACE_ENC ) + { + throw new java.io.IOException( "Invalid character in Base64 data." ); + } // end else: not white space either + } // end else: decoding + } // end write + + /** + * Calls {@link #write(int)} repeatedly until len + * bytes are written. + * + * @param theBytes array from which to read bytes + * @param off offset for array + * @param len max number of bytes to read into array + * @throws java.io.IOException + * @since 1.3 + */ + public void write( byte[] theBytes, int off, int len ) throws java.io.IOException + { + // Encoding suspended? + if( suspendEncoding ) + { + super.out.write( theBytes, off, len ); + return; + } // end if: supsended + + for( int i = 0; i < len; i++ ) + { + write( theBytes[ off + i ] ); + } // end for: each byte written + + } // end write + + /** + * Method added by PHIL. [Thanks, PHIL. -Rob] + * This pads the buffer without closing the stream. + * @throws java.io.IOException + */ + public void flushBase64() throws java.io.IOException + { + if( position > 0 ) + { + if( encode ) + { + out.write( encode3to4( b4, buffer, position, options ) ); + position = 0; + } // end if: encoding + else + { + throw new java.io.IOException( "Base64 input not properly padded." ); + } // end else: decoding + } // end if: buffer partially full + + } // end flush + + /** + * Flushes and closes (I think, in the superclass) the stream. + * + * @throws java.io.IOException + * @since 1.3 + */ + public void close() throws java.io.IOException + { + // 1. Ensure that pending characters are written + flushBase64(); + + // 2. Actually close the stream + // Base class both flushes and closes. + super.close(); + + buffer = null; + out = null; + } // end close + + /** + * Suspends encoding of the stream. + * May be helpful if you need to embed a piece of + * base640-encoded data in a stream. + * + * @throws java.io.IOException + * @since 1.5.1 + */ + public void suspendEncoding() throws java.io.IOException + { + flushBase64(); + this.suspendEncoding = true; + } // end suspendEncoding + + /** + * Resumes encoding of the stream. + * May be helpful if you need to embed a piece of + * base640-encoded data in a stream. + * + * @since 1.5.1 + */ + public void resumeEncoding() + { + this.suspendEncoding = false; + } // end resumeEncoding + + } // end inner class OutputStream + +} // end class Base64 diff --git a/src/main/java/org/owasp/esapi/codecs/CSSCodec.java b/src/main/java/org/owasp/esapi/codecs/CSSCodec.java new file mode 100644 index 000000000..9ffb60f32 --- /dev/null +++ b/src/main/java/org/owasp/esapi/codecs/CSSCodec.java @@ -0,0 +1,199 @@ +/** + * 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.codecs; + +import java.util.regex.Pattern; + +import org.owasp.esapi.codecs.ref.EncodingPatternPreservation; + +/** + * Implementation of the Codec interface for backslash encoding used in CSS. + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @since June 1, 2007 + * @see org.owasp.esapi.Encoder + */ +public class CSSCodec extends AbstractCharacterCodec +{ + private static final Character REPLACEMENT = '\ufffd'; + //rgb (###,###,###) OR rgb(###%,###%,###%) + //([rR][gG][bB])\s*\(\s*\d{1,3}\s*(\%)?\s*,\s*\d{1,3}\s*(\%)?\s*,\s*\d{1,3}\s*(\%)?\s*\) + private static final String RGB_TRPLT = "([rR][gG][bB])\\s*\\(\\s*\\d{1,3}\\s*(\\%)?\\s*,\\s*\\d{1,3}\\s*(\\%)?\\s*,\\s*\\d{1,3}\\s*(\\%)?\\s*\\)"; + private static final Pattern RGB_TRPLT_PATTERN = Pattern.compile(RGB_TRPLT); + + @Override + public String encode(char[] immune, String input) { + EncodingPatternPreservation tripletCheck = new EncodingPatternPreservation(RGB_TRPLT_PATTERN); + + String inputChk = tripletCheck.captureAndReplaceMatches(input); + + String result = super.encode(immune, inputChk); + + return tripletCheck.restoreOriginalContent(result); + } + /** + * {@inheritDoc} + * + * Returns backslash encoded character. + * + * @param immune + */ + public String encodeCharacter(char[] immune, Character c) { + // check for immune characters + if ( containsCharacter(c, immune ) ) { + return ""+c; + } + + // check for alphanumeric characters + String hex = super.getHexForNonAlphanumeric(c); + if ( hex == null ) { + return ""+c; + } + + // return the hex and end in whitespace to terminate + return "\\" + hex + " "; + } + + + /** + * {@inheritDoc} + * + * Returns the decoded version of the character starting at index, + * or null if no decoding is possible. + */ + @SuppressWarnings("fallthrough") + public Character decodeCharacter(PushbackSequence input) + { + input.mark(); + Character first = input.next(); + if (first == null || first != '\\') + { + input.reset(); + return null; + } + + Character second = input.next(); + if (second == null) { + input.reset(); + return null; + } + + /* From css 2.1 spec: + * http://www.w3.org/TR/CSS21/syndata.html#characters + * + * First, inside a string, a backslash followed by a + * newline is ignored (i.e., the string is deemed not + * to contain either the backslash or the newline). + * + * Second, it cancels the meaning of special CSS + * characters. Except within CSS comments, any character + * (except a hexadecimal digit, linefeed, carriage return, + * or form feed) can be escaped with a backslash to + * remove its special meaning. For example, "\"" is a string + * consisting of one double quote. Style sheet + * preprocessors must not remove these backslashes + * from a style sheet since that would change the style + * sheet's meaning. + * + * Third, backslash escapes allow authors to refer to + * characters they cannot easily put in a document. In + * this case, the backslash is followed by at most six + * hexadecimal digits (0..9A..F), which stand for the ISO + * 10646 ([ISO10646]) character with that number, which + * must not be zero. (It is undefined in CSS 2.1 what + * happens if a style sheet does contain a character with + * Unicode codepoint zero.) If a character in the range + * [0-9a-fA-F] follows the hexadecimal number, the end + * of the number needs to be made clear. There are two + * ways to do that: + * + * 1. with a space (or other white space character): + * "\26 B" ("&B"). In this case, user agents should + * treat a "CR/LF" pair (U+000D/U+000A) as a single + * white space character. + * + * 2. by providing exactly 6 hexadecimal digits: + * "\000026B" ("&B") + * + * In fact, these two methods may be combined. Only one + * white space character is ignored after a hexadecimal + * escape. Note that this means that a "real" space + * after the escape sequence must itself either be + * escaped or doubled. + * + * If the number is outside the range allowed by Unicode + * (e.g., "\110000" is above the maximum 10FFFF allowed in + * current Unicode), the UA may replace the escape with + * the "replacement character" (U+FFFD). If the character + * is to be displayed, the UA should show a visible + * symbol, such as a "missing character" glyph (cf. 15.2, + * point 5). + */ + + switch(second) + { // special whitespace cases. I assume they mean + // for all of these to qualify as a "new + // line." Otherwise there is no specification + // of what to do for \f + case '\r': + if(input.peek('\n')) + input.next(); + // fall through + case '\n': // Intentional fall through + case '\f': // Intentional fall through + // bs followed by new line replaced by nothing + case '\u0000': // skip NUL for now too + return decodeCharacter(input); + } + + if (!PushbackString.isHexDigit(second)) + { // non hex digit + return second; + } + + // Search for up to 6 hex digits following until a space + StringBuilder sb = new StringBuilder(); + sb.append(second); + for (int i = 0; i < 5; i++) + { + Character c = input.next(); + if(c == null || Character.isWhitespace(c)) + break; + if(PushbackString.isHexDigit(c)) + sb.append(c); + else + { + input.pushback(c); + break; + } + } + try + { + // parse the hex digit and create a character + int i = Integer.parseInt(sb.toString(), 16); + + if (Character.isValidCodePoint(i)) + return (char)i; + return REPLACEMENT; + } + catch (NumberFormatException e) + { + throw new IllegalStateException("Received a NumberFormateException parsing a string verified to be hex", e); + } + } + +} diff --git a/src/main/java/org/owasp/esapi/codecs/Codec.java b/src/main/java/org/owasp/esapi/codecs/Codec.java new file mode 100644 index 000000000..b46de6d5d --- /dev/null +++ b/src/main/java/org/owasp/esapi/codecs/Codec.java @@ -0,0 +1,145 @@ +/** + * 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.codecs; + + +/** + * 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. + *

+ * Other than the interfaces, very few of these concrete classes are intended to be used directly. + * Rather, most of them are used through implementations of the {@link org.owasp.esapi.Encoder} + * interface. While the OWASP team over the years have made every effort to be extra cautious, the + * various {@code Codec} implementations can offer NO GUARANTEE of safety if the client is + * using these {@code Codec} classes directly. Therefore, if the client is using + * these classes directly, it is highly advised to practice security-in-depth + * and also perform canonicalization, followed by strict input validation, both + * prior to encoding and after decoding, to protect your application from input-based + * attacks. + *

+ * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @since June 1, 2007 + * + * @author Matt Seil (mseil .at. owasp.org) + * @since June 1, 2017 + * @see org.owasp.esapi.Encoder + * @see org.owasp.esapi.Validator + */ +public interface Codec { + /** + * Encode a String so that it can be safely used in a specific context. + * + * @param immune + * @param input + * the String to encode + * @return the encoded String + */ + public String encode(char[] immune, String input); + + /** + * Default implementation that should be overridden in specific codecs. + * + * @param immune + * array of chars to NOT encode. Use with caution. + * @param c + * the Character to encode + * @return + * the encoded Character + */ + public String encodeCharacter( char[] immune, Character c ); + + /** + * Default codepoint implementation that should be overridden in specific codecs. + * + * @param immune + * @param codePoint + * the integer to encode + * @return + * the encoded Character + */ + public String encodeCharacter( char[] immune, int codePoint ); + + /** + * Decode a String that was encoded using the encode method in this Class + * + * @param input + * the String to decode + * @return + * the decoded String + */ + public String decode(String input); + + /** + * Returns the decoded version of the next character from the input string and advances the + * current character in the {@code PushbackSequence}. If the current character is not encoded, this + * method MUST reset the {@code PushbackString}. + * + * @param input the Character to decode + * + * @return the decoded Character + */ + public T decodeCharacter( PushbackSequence input ); + + /** + * Lookup the hex value of any character that is not alphanumeric. + * @param c The character to lookup. + * @return return null if alphanumeric or the character code in hex. + */ + public String getHexForNonAlphanumeric(char c); + + /** + * Lookup the hex value of any character that is not alphanumeric. + * @param c The character to lookup. + * @return return null if alphanumeric or the character code in hex. + */ + public String getHexForNonAlphanumeric(int c); + + /** + * Convert the {@code char} parameter to its octal representation. + * @param c the character for which to return the new representation. + * @return the octal representation. + */ + public String toOctal(char c); + + /** + * Convert the {@code char} parameter to its hexadecimal representation. + * @param c the character for which to return the new representation. + * @return the hexadecimal representation. + */ + public String toHex(char c); + + /** + * Convert the {@code int} parameter to its hexadecimal representation. + * @param c the character for which to return the new representation. + * @return the hexadecimal representation. + */ + public String toHex(int c); + + /** + * Utility to search a char[] for a specific char. + * + * @param c + * @param array + * @return True if the supplied array contains the specified character. False otherwise. + */ + public boolean containsCharacter( char c, char[] array ); + +} diff --git a/src/main/java/org/owasp/esapi/codecs/DB2Codec.java b/src/main/java/org/owasp/esapi/codecs/DB2Codec.java new file mode 100644 index 000000000..61d1f70cd --- /dev/null +++ b/src/main/java/org/owasp/esapi/codecs/DB2Codec.java @@ -0,0 +1,81 @@ +/** + * 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. + */ +package org.owasp.esapi.codecs; + + +/** + * Implementation of the Codec interface for IBM Db2 strings. + * This function will only protect you from SQLi in limited situations. + * To improve your chances of success, you made also need to do some + * additional canonicalization and input validation first. Before using this class, + * please be sure to read the "SECURITY WARNING" in + * {@link org.owasp.esapi.Encoder#encodeForSQL} + * before using this particular {@link org.owasp.esapi.codecs.Codec} and raising your hope of finding + * a silver bullet to kill all the SQLi werewolves. + * + * @author Sivasankar Tanakala (stanakal@TRS.NYC.NY.US) + * @since October 26, 2010 + * @see org.owasp.esapi.Encoder + * @see + * ESAPI Security Bulletin #13 + * @deprecated This class 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 +public class DB2Codec extends AbstractCharacterCodec { + + public String encodeCharacter(char[] immune, Character c) { + + if (c.charValue() == '\'') + return "\'\'"; + + if (c.charValue() == ';') + return "."; + + return "" + c; + } + + public Character decodeCharacter(PushbackString input) { + + input.mark(); + Character first = input.next(); + + if (first == null) { + input.reset(); + return null; + } + + // if this is not an encoded character, return null + + if (first.charValue() != '\'') { + input.reset(); + return null; + } + + Character second = input.next(); + + if (second == null) { + input.reset(); + return null; + } + + // if this is not an encoded character, return null + if (second.charValue() != '\'') { + input.reset(); + return null; + } + + return (Character.valueOf('\'')); + } +} diff --git a/src/main/java/org/owasp/esapi/codecs/HTMLEntityCodec.java b/src/main/java/org/owasp/esapi/codecs/HTMLEntityCodec.java new file mode 100644 index 000000000..d71b6e536 --- /dev/null +++ b/src/main/java/org/owasp/esapi/codecs/HTMLEntityCodec.java @@ -0,0 +1,598 @@ +/** + * 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) 2017 - 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 Matt Seil (mseil .at. owasp.org) + * @created 2017 + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @created 2007 + */ +package org.owasp.esapi.codecs; + +import java.util.HashMap; +import java.util.Collections; +import java.util.Map; +import java.util.Map.Entry; + +/** + * Implementation of the Codec interface for HTML entity encoding. + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @since June 1, 2007 + * + * @author Matt Seil (mseil .at. owasp.org) (mseil .at. owasp.org) + * + * @see org.owasp.esapi.Encoder + */ +public class HTMLEntityCodec extends AbstractIntegerCodec +{ + private static final char REPLACEMENT_CHAR = '\ufffd'; + private static final String REPLACEMENT_HEX = "fffd"; + private static final String REPLACEMENT_STR = "" + REPLACEMENT_CHAR; + private static final Map characterToEntityMap = mkCharacterToEntityMap(); + + private static final Trie entityToCharacterTrie = mkEntityToCharacterTrie(); + + /** + * + */ + public HTMLEntityCodec() { + } + + /** + * Given an array of {@code char}, scan the input {@code String} and encode unsafe + * codePoints, except for codePoints passed into the {@code char} array. + *

+ * WARNING: This method will silently discard an invalid code point according to + * the result of {@code Character.isValidCodePoint( int )} method. + * + * {@inheritDoc} + */ + @Override + public String encode(char[] immune, String input) { + StringBuilder sb = new StringBuilder(); + for(int offset = 0; offset < input.length(); ){ + final int point = input.codePointAt(offset); + if(Character.isValidCodePoint(point)){ + sb.append(encodeCharacter(immune, point)); + } + offset += Character.charCount(point); + } + return sb.toString(); + } + + /** + * {@inheritDoc} + * + * Encodes a codePoint for safe use in an HTML entity field. + * @param immune + */ + @Override + public String encodeCharacter( char[] immune, int codePoint ) { + + // check for immune characters + // Cast the codePoint to a char because we want to limit immunity to the BMP field only. + if ( containsCharacter( (char) codePoint, immune ) && Character.isValidCodePoint(codePoint)) { + return new StringBuilder().appendCodePoint(codePoint).toString(); + } + + // check for alphanumeric characters + String hex = super.getHexForNonAlphanumeric(codePoint); + if ( hex == null && Character.isValidCodePoint(codePoint)) { + return new StringBuilder().appendCodePoint(codePoint).toString(); + } + // check for illegal characters + if ( ( codePoint <= 0x1f + && codePoint != '\t' + && codePoint != '\n' + && codePoint != '\r' ) + || ( codePoint >= 0x7f && codePoint <= 0x9f ) ) + { + hex = REPLACEMENT_HEX; // Let's entity encode this instead of returning it + codePoint = REPLACEMENT_CHAR; + } + + // check if there's a defined entity + String entityName = characterToEntityMap.get(codePoint); + if (entityName != null) { + return "&" + entityName + ";"; + } + + // return the hex entity as suggested in the spec + return "&#x" + hex + ";"; + } + + /** + * {@inheritDoc} + * + * 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 semicolon, upper/lower case: + * &#dddd; + * &#xhhhh; + * &name; + */ + public Integer decodeCharacter( PushbackSequence input ) { + input.mark(); + Integer first = input.next(); + if ( first == null ) { + input.reset(); + return null; + } + + // if this is not an encoded character, return null + if (first != '&' ) { + input.reset(); + return null; + } + + // test for numeric encodings + Integer second = input.next(); + if ( second == null ) { + input.reset(); + return null; + } + + if (second == '#' ) { + // handle numbers + Integer c = getNumericEntity( input ); + if ( c != null ) return c; + } else if ( Character.isLetter( second ) ) { + // handle entities + input.pushback( second ); + Integer c = getNamedEntity( input ); + if ( c != null ) return c; + } + input.reset(); + return null; + } + + /** + * getNumericEntry checks input to see if it is a numeric entity + * + * @param input + * The input to test for being a numeric entity + * + * @return + * null if input is null, the character of input after decoding + */ + private Integer getNumericEntity( PushbackSequence input ) { + Integer first = input.peek(); + if ( first == null ) return null; + + if (first == 'x' || first == 'X' ) { + input.next(); + return parseHex( input ); + } + return parseNumber( input ); + } + + /** + * Parse a decimal number, such as those from JavaScript's String.fromCharCode(value) + * + * @param input + * decimal encoded string, such as 65 + * @return + * character representation of this decimal value, e.g. A + * @throws NumberFormatException + */ + private Integer parseNumber( PushbackSequence input ) { + StringBuilder sb = new StringBuilder(); + while( input.hasNext() ) { + Integer c = input.peek(); + + // if character is a digit then add it on and keep going + if ( Character.isDigit( c ) && Character.isValidCodePoint(c) ) { + sb.appendCodePoint( c ); + input.next(); + + // if character is a semicolon, eat it and quit + } else if (c == ';' ) { + input.next(); + break; + + // otherwise just quit + } else { + break; + } + } + try { + int i = Integer.parseInt(sb.toString()); + if (Character.isValidCodePoint(i)) { + return i; + } + } catch( NumberFormatException e ) { + // throw an exception for malformed entity? + } + return null; + } + + /** + * Parse a hex encoded entity + * + * @param input + * Hex encoded input (such as 437ae;) + * @return + * A single character from the string + * @throws NumberFormatException + */ + private Integer parseHex( PushbackSequence input ) { + StringBuilder sb = new StringBuilder(); + while( input.hasNext() ) { + Integer c = input.peek(); + + // if character is a hex digit then add it on and keep going + //This statement implicitly tests for Character.isValidCodePoint(int) + if ( "0123456789ABCDEFabcdef".indexOf(c) != -1 ) { + sb.appendCodePoint( c ); + input.next(); + + // if character is a semicolon, eat it and quit + } else if (c == ';' ) { + input.next(); + break; + + // otherwise just quit + } else { + break; + } + } + try { + int i = Integer.parseInt(sb.toString(), 16); + if (Character.isValidCodePoint(i)) { + return i; + } + } catch( NumberFormatException e ) { + // throw an exception for malformed entity? + } + return null; + } + + /** + * + * 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: + * &aa; + * &aaa; + * &aaaa; + * &aaaaa; + * &aaaaaa; + * &aaaaaaa; + * + * @param input + * A string containing a named entity like " + * @return + * Returns the decoded version of the character starting at index, or null if no decoding is possible. + */ + private Integer getNamedEntity( PushbackSequence input ) { + StringBuilder possible = new StringBuilder(); + Entry entry; + int len; + + // kludge around PushbackString.... + len = Math.min(input.remainder().length(), entityToCharacterTrie.getMaxKeyLength()); + for(int i=0;i exactEntry = entityToCharacterTrie.getLongestMatch(possibleStringLowerCase); + if(exactEntry != null) entry = exactEntry; + } + if(entry == null) return null; // no match, caller will reset input + } + + // fixup input + input.reset(); + input.next(); // read & + len = entry.getKey().length(); // what matched's length + for(int i=0;i mkCharacterToEntityMap() + { + Map map = new HashMap(252); + + map.put(34, "quot"); /* quotation mark */ + map.put(38, "amp"); /* ampersand */ + map.put(60, "lt"); /* less-than sign */ + map.put(62, "gt"); /* greater-than sign */ + map.put(160, "nbsp"); /* no-break space */ + map.put(161, "iexcl"); /* inverted exclamation mark */ + map.put(162, "cent"); /* cent sign */ + map.put(163, "pound"); /* pound sign */ + map.put(164, "curren"); /* currency sign */ + map.put(165, "yen"); /* yen sign */ + map.put(166, "brvbar"); /* broken bar */ + map.put(167, "sect"); /* section sign */ + map.put(168, "uml"); /* diaeresis */ + map.put(169, "copy"); /* copyright sign */ + map.put(170, "ordf"); /* feminine ordinal indicator */ + map.put(171, "laquo"); /* left-pointing double angle quotation mark */ + map.put(172, "not"); /* not sign */ + map.put(173, "shy"); /* soft hyphen */ + map.put(174, "reg"); /* registered sign */ + map.put(175, "macr"); /* macron */ + map.put(176, "deg"); /* degree sign */ + map.put(177, "plusmn"); /* plus-minus sign */ + map.put(178, "sup2"); /* superscript two */ + map.put(179, "sup3"); /* superscript three */ + map.put(180, "acute"); /* acute accent */ + map.put(181, "micro"); /* micro sign */ + map.put(182, "para"); /* pilcrow sign */ + map.put(183, "middot"); /* middle dot */ + map.put(184, "cedil"); /* cedilla */ + map.put(185, "sup1"); /* superscript one */ + map.put(186, "ordm"); /* masculine ordinal indicator */ + map.put(187, "raquo"); /* right-pointing double angle quotation mark */ + map.put(188, "frac14"); /* vulgar fraction one quarter */ + map.put(189, "frac12"); /* vulgar fraction one half */ + map.put(190, "frac34"); /* vulgar fraction three quarters */ + map.put(191, "iquest"); /* inverted question mark */ + map.put(192, "Agrave"); /* Latin capital letter a with grave */ + map.put(193, "Aacute"); /* Latin capital letter a with acute */ + map.put(194, "Acirc"); /* Latin capital letter a with circumflex */ + map.put(195, "Atilde"); /* Latin capital letter a with tilde */ + map.put(196, "Auml"); /* Latin capital letter a with diaeresis */ + map.put(197, "Aring"); /* Latin capital letter a with ring above */ + map.put(198, "AElig"); /* Latin capital letter ae */ + map.put(199, "Ccedil"); /* Latin capital letter c with cedilla */ + map.put(200, "Egrave"); /* Latin capital letter e with grave */ + map.put(201, "Eacute"); /* Latin capital letter e with acute */ + map.put(202, "Ecirc"); /* Latin capital letter e with circumflex */ + map.put(203, "Euml"); /* Latin capital letter e with diaeresis */ + map.put(204, "Igrave"); /* Latin capital letter i with grave */ + map.put(205, "Iacute"); /* Latin capital letter i with acute */ + map.put(206, "Icirc"); /* Latin capital letter i with circumflex */ + map.put(207, "Iuml"); /* Latin capital letter i with diaeresis */ + map.put(208, "ETH"); /* Latin capital letter eth */ + map.put(209, "Ntilde"); /* Latin capital letter n with tilde */ + map.put(210, "Ograve"); /* Latin capital letter o with grave */ + map.put(211, "Oacute"); /* Latin capital letter o with acute */ + map.put(212, "Ocirc"); /* Latin capital letter o with circumflex */ + map.put(213, "Otilde"); /* Latin capital letter o with tilde */ + map.put(214, "Ouml"); /* Latin capital letter o with diaeresis */ + map.put(215, "times"); /* multiplication sign */ + map.put(216, "Oslash"); /* Latin capital letter o with stroke */ + map.put(217, "Ugrave"); /* Latin capital letter u with grave */ + map.put(218, "Uacute"); /* Latin capital letter u with acute */ + map.put(219, "Ucirc"); /* Latin capital letter u with circumflex */ + map.put(220, "Uuml"); /* Latin capital letter u with diaeresis */ + map.put(221, "Yacute"); /* Latin capital letter y with acute */ + map.put(222, "THORN"); /* Latin capital letter thorn */ + map.put(223, "szlig"); /* Latin small letter sharp sXCOMMAX German Eszett */ + map.put(224, "agrave"); /* Latin small letter a with grave */ + map.put(225, "aacute"); /* Latin small letter a with acute */ + map.put(226, "acirc"); /* Latin small letter a with circumflex */ + map.put(227, "atilde"); /* Latin small letter a with tilde */ + map.put(228, "auml"); /* Latin small letter a with diaeresis */ + map.put(229, "aring"); /* Latin small letter a with ring above */ + map.put(230, "aelig"); /* Latin lowercase ligature ae */ + map.put(231, "ccedil"); /* Latin small letter c with cedilla */ + map.put(232, "egrave"); /* Latin small letter e with grave */ + map.put(233, "eacute"); /* Latin small letter e with acute */ + map.put(234, "ecirc"); /* Latin small letter e with circumflex */ + map.put(235, "euml"); /* Latin small letter e with diaeresis */ + map.put(236, "igrave"); /* Latin small letter i with grave */ + map.put(237, "iacute"); /* Latin small letter i with acute */ + map.put(238, "icirc"); /* Latin small letter i with circumflex */ + map.put(239, "iuml"); /* Latin small letter i with diaeresis */ + map.put(240, "eth"); /* Latin small letter eth */ + map.put(241, "ntilde"); /* Latin small letter n with tilde */ + map.put(242, "ograve"); /* Latin small letter o with grave */ + map.put(243, "oacute"); /* Latin small letter o with acute */ + map.put(244, "ocirc"); /* Latin small letter o with circumflex */ + map.put(245, "otilde"); /* Latin small letter o with tilde */ + map.put(246, "ouml"); /* Latin small letter o with diaeresis */ + map.put(247, "divide"); /* division sign */ + map.put(248, "oslash"); /* Latin small letter o with stroke */ + map.put(249, "ugrave"); /* Latin small letter u with grave */ + map.put(250, "uacute"); /* Latin small letter u with acute */ + map.put(251, "ucirc"); /* Latin small letter u with circumflex */ + map.put(252, "uuml"); /* Latin small letter u with diaeresis */ + map.put(253, "yacute"); /* Latin small letter y with acute */ + map.put(254, "thorn"); /* Latin small letter thorn */ + map.put(255, "yuml"); /* Latin small letter y with diaeresis */ + map.put(338, "OElig"); /* Latin capital ligature oe */ + map.put(339, "oelig"); /* Latin small ligature oe */ + map.put(352, "Scaron"); /* Latin capital letter s with caron */ + map.put(353, "scaron"); /* Latin small letter s with caron */ + map.put(376, "Yuml"); /* Latin capital letter y with diaeresis */ + map.put(402, "fnof"); /* Latin small letter f with hook */ + map.put(710, "circ"); /* modifier letter circumflex accent */ + map.put(732, "tilde"); /* small tilde */ + map.put(913, "Alpha"); /* Greek capital letter alpha */ + map.put(914, "Beta"); /* Greek capital letter beta */ + map.put(915, "Gamma"); /* Greek capital letter gamma */ + map.put(916, "Delta"); /* Greek capital letter delta */ + map.put(917, "Epsilon"); /* Greek capital letter epsilon */ + map.put(918, "Zeta"); /* Greek capital letter zeta */ + map.put(919, "Eta"); /* Greek capital letter eta */ + map.put(920, "Theta"); /* Greek capital letter theta */ + map.put(921, "Iota"); /* Greek capital letter iota */ + map.put(922, "Kappa"); /* Greek capital letter kappa */ + map.put(923, "Lambda"); /* Greek capital letter lambda */ + map.put(924, "Mu"); /* Greek capital letter mu */ + map.put(925, "Nu"); /* Greek capital letter nu */ + map.put(926, "Xi"); /* Greek capital letter xi */ + map.put(927, "Omicron"); /* Greek capital letter omicron */ + map.put(928, "Pi"); /* Greek capital letter pi */ + map.put(929, "Rho"); /* Greek capital letter rho */ + map.put(931, "Sigma"); /* Greek capital letter sigma */ + map.put(932, "Tau"); /* Greek capital letter tau */ + map.put(933, "Upsilon"); /* Greek capital letter upsilon */ + map.put(934, "Phi"); /* Greek capital letter phi */ + map.put(935, "Chi"); /* Greek capital letter chi */ + map.put(936, "Psi"); /* Greek capital letter psi */ + map.put(937, "Omega"); /* Greek capital letter omega */ + map.put(945, "alpha"); /* Greek small letter alpha */ + map.put(946, "beta"); /* Greek small letter beta */ + map.put(947, "gamma"); /* Greek small letter gamma */ + map.put(948, "delta"); /* Greek small letter delta */ + map.put(949, "epsilon"); /* Greek small letter epsilon */ + map.put(950, "zeta"); /* Greek small letter zeta */ + map.put(951, "eta"); /* Greek small letter eta */ + map.put(952, "theta"); /* Greek small letter theta */ + map.put(953, "iota"); /* Greek small letter iota */ + map.put(954, "kappa"); /* Greek small letter kappa */ + map.put(955, "lambda"); /* Greek small letter lambda */ + map.put(956, "mu"); /* Greek small letter mu */ + map.put(957, "nu"); /* Greek small letter nu */ + map.put(958, "xi"); /* Greek small letter xi */ + map.put(959, "omicron"); /* Greek small letter omicron */ + map.put(960, "pi"); /* Greek small letter pi */ + map.put(961, "rho"); /* Greek small letter rho */ + map.put(962, "sigmaf"); /* Greek small letter final sigma */ + map.put(963, "sigma"); /* Greek small letter sigma */ + map.put(964, "tau"); /* Greek small letter tau */ + map.put(965, "upsilon"); /* Greek small letter upsilon */ + map.put(966, "phi"); /* Greek small letter phi */ + map.put(967, "chi"); /* Greek small letter chi */ + map.put(968, "psi"); /* Greek small letter psi */ + map.put(969, "omega"); /* Greek small letter omega */ + map.put(977, "thetasym"); /* Greek theta symbol */ + map.put(978, "upsih"); /* Greek upsilon with hook symbol */ + map.put(982, "piv"); /* Greek pi symbol */ + map.put(8194, "ensp"); /* en space */ + map.put(8195, "emsp"); /* em space */ + map.put(8201, "thinsp"); /* thin space */ + map.put(8204, "zwnj"); /* zero width non-joiner */ + map.put(8205, "zwj"); /* zero width joiner */ + map.put(8206, "lrm"); /* left-to-right mark */ + map.put(8207, "rlm"); /* right-to-left mark */ + map.put(8211, "ndash"); /* en dash */ + map.put(8212, "mdash"); /* em dash */ + map.put(8216, "lsquo"); /* left single quotation mark */ + map.put(8217, "rsquo"); /* right single quotation mark */ + map.put(8218, "sbquo"); /* single low-9 quotation mark */ + map.put(8220, "ldquo"); /* left double quotation mark */ + map.put(8221, "rdquo"); /* right double quotation mark */ + map.put(8222, "bdquo"); /* double low-9 quotation mark */ + map.put(8224, "dagger"); /* dagger */ + map.put(8225, "Dagger"); /* double dagger */ + map.put(8226, "bull"); /* bullet */ + map.put(8230, "hellip"); /* horizontal ellipsis */ + map.put(8240, "permil"); /* per mille sign */ + map.put(8242, "prime"); /* prime */ + map.put(8243, "Prime"); /* double prime */ + map.put(8249, "lsaquo"); /* single left-pointing angle quotation mark */ + map.put(8250, "rsaquo"); /* single right-pointing angle quotation mark */ + map.put(8254, "oline"); /* overline */ + map.put(8260, "frasl"); /* fraction slash */ + map.put(8364, "euro"); /* euro sign */ + map.put(8465, "image"); /* black-letter capital i */ + map.put(8472, "weierp"); /* script capital pXCOMMAX Weierstrass p */ + map.put(8476, "real"); /* black-letter capital r */ + map.put(8482, "trade"); /* trademark sign */ + map.put(8501, "alefsym"); /* alef symbol */ + map.put(8592, "larr"); /* leftwards arrow */ + map.put(8593, "uarr"); /* upwards arrow */ + map.put(8594, "rarr"); /* rightwards arrow */ + map.put(8595, "darr"); /* downwards arrow */ + map.put(8596, "harr"); /* left right arrow */ + map.put(8629, "crarr"); /* downwards arrow with corner leftwards */ + map.put(8656, "lArr"); /* leftwards double arrow */ + map.put(8657, "uArr"); /* upwards double arrow */ + map.put(8658, "rArr"); /* rightwards double arrow */ + map.put(8659, "dArr"); /* downwards double arrow */ + map.put(8660, "hArr"); /* left right double arrow */ + map.put(8704, "forall"); /* for all */ + map.put(8706, "part"); /* partial differential */ + map.put(8707, "exist"); /* there exists */ + map.put(8709, "empty"); /* empty set */ + map.put(8711, "nabla"); /* nabla */ + map.put(8712, "isin"); /* element of */ + map.put(8713, "notin"); /* not an element of */ + map.put(8715, "ni"); /* contains as member */ + map.put(8719, "prod"); /* n-ary product */ + map.put(8721, "sum"); /* n-ary summation */ + map.put(8722, "minus"); /* minus sign */ + map.put(8727, "lowast"); /* asterisk operator */ + map.put(8730, "radic"); /* square root */ + map.put(8733, "prop"); /* proportional to */ + map.put(8734, "infin"); /* infinity */ + map.put(8736, "ang"); /* angle */ + map.put(8743, "and"); /* logical and */ + map.put(8744, "or"); /* logical or */ + map.put(8745, "cap"); /* intersection */ + map.put(8746, "cup"); /* union */ + map.put(8747, "int"); /* integral */ + map.put(8756, "there4"); /* therefore */ + map.put(8764, "sim"); /* tilde operator */ + map.put(8773, "cong"); /* congruent to */ + map.put(8776, "asymp"); /* almost equal to */ + map.put(8800, "ne"); /* not equal to */ + map.put(8801, "equiv"); /* identical toXCOMMAX equivalent to */ + map.put(8804, "le"); /* less-than or equal to */ + map.put(8805, "ge"); /* greater-than or equal to */ + map.put(8834, "sub"); /* subset of */ + map.put(8835, "sup"); /* superset of */ + map.put(8836, "nsub"); /* not a subset of */ + map.put(8838, "sube"); /* subset of or equal to */ + map.put(8839, "supe"); /* superset of or equal to */ + map.put(8853, "oplus"); /* circled plus */ + map.put(8855, "otimes"); /* circled times */ + map.put(8869, "perp"); /* up tack */ + map.put(8901, "sdot"); /* dot operator */ + map.put(8968, "lceil"); /* left ceiling */ + map.put(8969, "rceil"); /* right ceiling */ + map.put(8970, "lfloor"); /* left floor */ + map.put(8971, "rfloor"); /* right floor */ + map.put(9001, "lang"); /* left-pointing angle bracket */ + map.put(9002, "rang"); /* right-pointing angle bracket */ + map.put(9674, "loz"); /* lozenge */ + map.put(9824, "spades"); /* black spade suit */ + map.put(9827, "clubs"); /* black club suit */ + map.put(9829, "hearts"); /* black heart suit */ + map.put(9830, "diams"); /* black diamond suit */ + + return Collections.unmodifiableMap(map); + } + + /** + * Build a unmodifiable Trie from entitiy Name to Character + * @return Unmodifiable trie. + */ + private static synchronized Trie mkEntityToCharacterTrie() + { + Trie trie = new HashTrie(); + + for(Map.Entry entry : characterToEntityMap.entrySet()) + trie.put(entry.getValue(),entry.getKey()); + return Trie.Util.unmodifiable(trie); + } +} diff --git a/src/main/java/org/owasp/esapi/codecs/HashTrie.java b/src/main/java/org/owasp/esapi/codecs/HashTrie.java new file mode 100644 index 000000000..cdc9932aa --- /dev/null +++ b/src/main/java/org/owasp/esapi/codecs/HashTrie.java @@ -0,0 +1,608 @@ +package org.owasp.esapi.codecs; + +import java.io.IOException; +import java.io.PushbackReader; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.owasp.esapi.util.NullSafe; + +/** + * Trie implementation for CharSequence keys. This uses HashMaps for each + * level instead of the traditional array. This is done as with unicode, + * each level's array would be 64k entries. + * + * NOTE:
+ *
    + *
  • @see java.util.Map.remove(Object) is not supported.
  • + *
  • + * If deletion support is added, the max key length will need work or removal. + *
  • + *
  • Null values are not supported.
  • + *
+ * + * @author Ed Schaller + */ +public class HashTrie implements Trie +{ + private static class Entry implements Map.Entry + { + private CharSequence key; + private T value; + + Entry(CharSequence key, T value) + { + this.key = key; + this.value = value; + } + + /** + * Convenience instantiator. + * @param key The key for the new instance + * @param keyLength The length of the key to use + * @param value The value for the new instance + * @return null if key or value is null + * new Entry(key,value) if {@link CharSequence#length()} == keyLength + * new Entry(key.subSequence(0,keyLength),value) otherwise + */ + static Entry newInstanceIfNeeded(CharSequence key, int keyLength, T value) + { + if(value == null || key == null) + return null; + if(key.length() > keyLength) + key = key.subSequence(0,keyLength); + return new Entry(key,value); + } + + /** + * Convenience instantiator. + * @param key The key for the new instance + * @param value The value for the new instance + * @return null if key or value is null + * new Entry(key,value) otherwise + */ + static Entry newInstanceIfNeeded(CharSequence key, T value) + { + if(value == null || key == null) + return null; + return new Entry(key,value); + } + + /*************/ + /* Map.Entry */ + /*************/ + + public CharSequence getKey() + { + return key; + } + + public T getValue() + { + return value; + } + + public T setValue(T value) + { + throw new UnsupportedOperationException(); + } + + /********************/ + /* java.lang.Object */ + /********************/ + + public boolean equals(Map.Entry other) + { + return (NullSafe.equals(key, other.getKey()) && NullSafe.equals(value, other.getValue())); + } + + @Override + public boolean equals(Object o) + { + if(o instanceof Map.Entry) + return equals((Map.Entry)o); + return false; + } + + @Override + public int hashCode() + { + return NullSafe.hashCode(key) ^ NullSafe.hashCode(value); + } + + @Override + public String toString() + { + return NullSafe.toString(key) + " => " + NullSafe.toString(value); + } + } + + /** + * Node inside the trie. + */ + private static class Node + { + private T value = null; + private Map> nextMap; + + /** + * Create a new Map for a node level. This is here so + * that if the underlying * Map implementation needs to + * be switched it is easily done. + * @return A new Map for use. + */ + private static Map> newNodeMap() + { + return new HashMap>(); + } + + /** + * Create a new Map for a node level. This is here so + * that if the underlying * Map implementation needs to + * be switched it is easily done. + * @param prev Previous map to use to populate the + * new map. + * @return A new Map for use. + */ + private static Map> newNodeMap(Map> prev) + { + return new HashMap>(prev); + } + + /** + * Set the value for the key terminated at this node. + * @param value The value for this key. + */ + void setValue(T value) + { + this.value = value; + } + + /** + * Get the node for the specified character. + * @param ch The next character to look for. + * @return The node requested or null if it is not + * present. + */ + Node getNextNode(Character ch) + { + if(nextMap == null) + return null; + return nextMap.get(ch); + } + + /** + * Recursively add a key. + * @param key The key being added. + * @param pos The position in key that is being handled + * at this level. + */ + T put(CharSequence key, int pos, T addValue) + { + Node nextNode; + Character ch; + T old; + + if(key.length() == pos) + { // at terminating node + old = value; + setValue(addValue); + return old; + } + ch = key.charAt(pos); + if(nextMap == null) + { + nextMap = newNodeMap(); + nextNode = new Node(); + nextMap.put(ch, nextNode); + } + else if((nextNode = nextMap.get(ch))==null) + { + nextNode = new Node(); + nextMap.put(ch,nextNode); + } + return nextNode.put(key,pos+1,addValue); + } + + /** + * Recursively lookup a key's value. + * @param key The key being looked up. + * @param pos The position in the key that is being + * looked up at this level. + * @return The value associated with the key or null if none exists. + */ + T get(CharSequence key, int pos) + { + Node nextNode; + + if(key.length() <= pos) // <= instead of == just in case + return value; // no value is null which is also not found + if((nextNode = getNextNode(key.charAt(pos)))==null) + return null; + return nextNode.get(key,pos+1); + } + + /** + * Recursively lookup the longest key match. + * @param key The key being looked up. + * @param pos The position in the key that is being + * looked up at this level. + * @return The Entry associated with the longest key match or null if none exists. + */ + Entry getLongestMatch(CharSequence key, int pos) + { + Node nextNode; + Entry ret; + + if(key.length() <= pos) // <= instead of == just in case + return Entry.newInstanceIfNeeded(key,value); + if((nextNode = getNextNode(key.charAt(pos)))==null) + { // last in trie... return ourselves + return Entry.newInstanceIfNeeded(key,pos,value); + } + if((ret = nextNode.getLongestMatch(key, pos+1))!=null) + return ret; + return Entry.newInstanceIfNeeded(key,pos,value); + } + + /** + * Recursively lookup the longest key match. + * @param keyIn Where to read the key from + * @param key The key that is being looked up at this level. + * @return The Entry associated with the longest key + * match or null if none exists. + */ + Entry getLongestMatch(PushbackReader keyIn, StringBuilder key) throws IOException + { + Node nextNode; + Entry ret; + int c; + char ch; + int prevLen; + + // read next key char and append to key... + if((c = keyIn.read())<0) + // end of input, return what we have currently + return Entry.newInstanceIfNeeded(key,value); + ch = (char)c; + prevLen = key.length(); + key.append(ch); + + if((nextNode = getNextNode(ch))==null) + { // last in trie... return ourselves + return Entry.newInstanceIfNeeded(key,value); + } + if((ret = nextNode.getLongestMatch(keyIn, key))!=null) + return ret; + + // undo reading of key char and appending to key... + key.setLength(prevLen); + keyIn.unread(c); + + return Entry.newInstanceIfNeeded(key,value); + } + + /** + * Recursively rebuild the internal maps. + */ + void remap() + { + if(nextMap == null) + return; + nextMap = newNodeMap(nextMap); + for(Node node : nextMap.values()) + node.remap(); + } + + /** + * Recursively search for a value. + * @param toFind The value to search for + * @return true if the value was found + * false otherwise + */ + boolean containsValue(Object toFind) + { + if(value != null && toFind.equals(value)) + return true; + if(nextMap == null) + return false; + for(Node node : nextMap.values()) + if(node.containsValue(toFind)) + return true; + return false; + } + + /** + * Recursively build values. + * @param values List being built. + * @return true if the value was found + * false otherwise + */ + Collection values(Collection values) + { + if(value != null) + values.add(value); + if(nextMap == null) + return values; + for(Node node : nextMap.values()) + node.values(values); + return values; + } + + /** + * Recursively build a key set. + * @param key StringBuilder with our key. + * @param keys Set to add to + * @return keys with additions + */ + Set keySet(StringBuilder key, Set keys) + { + int len = key.length(); + + if(value != null) + // MUST toString here + keys.add(key.toString()); + if(nextMap != null && nextMap.size() > 0) + { + key.append('X'); + for(Map.Entry> entry : nextMap.entrySet()) + { + key.setCharAt(len,entry.getKey()); + entry.getValue().keySet(key,keys); + } + key.setLength(len); + } + return keys; + } + + /** + * Recursively build a entry set. + * @param key StringBuilder with our key. + * @param entries Set to add to + * @return entries with additions + */ + Set> entrySet(StringBuilder key, Set> entries) + { + int len = key.length(); + + if(value != null) + // MUST toString here + entries.add(new Entry(key.toString(),value)); + if(nextMap != null && nextMap.size() > 0) + { + key.append('X'); + for(Map.Entry> entry : nextMap.entrySet()) + { + key.setCharAt(len,entry.getKey()); + entry.getValue().entrySet(key,entries); + } + key.setLength(len); + } + return entries; + } + } + + private Node root; + private int maxKeyLen; + private int size; + + public HashTrie() + { + clear(); + } + + /** + * Get the key value entry whose key is the longest prefix match. + * @param key The key to lookup + * @return Entry with the longest matching key. + */ + public Map.Entry getLongestMatch(CharSequence key) + { + if(root == null || key == null) + return null; + return root.getLongestMatch(key, 0); + } + + /** + * Get the key value entry whose key is the longest prefix match. + * @param keyIn Pushback reader to read the key from. This should + * have a buffer at least as large as {@link #getMaxKeyLength()} + * or an IOException may be thrown backing up. + * @return Entry with the longest matching key. + * @throws IOException if keyIn.read() or keyIn.unread() does. + */ + public Map.Entry getLongestMatch(PushbackReader keyIn) throws IOException + { + if(root == null || keyIn == null) + return null; + return root.getLongestMatch(keyIn, new StringBuilder()); + } + + /** + * Get the maximum key length. + * @return max key length. + */ + public int getMaxKeyLength() + { + return maxKeyLen; + } + + /*****************/ + /* java.util.Map */ + /*****************/ + + /** + * Clear all entries. + */ + public void clear() + { + root = null; + maxKeyLen = -1; + size = 0; + } + + /** {@inheritDoc} */ + public boolean containsKey(Object key) + { + return (get(key) != null); + } + + /** {@inheritDoc} */ + public boolean containsValue(Object value) + { + if(root == null) + return false; + return root.containsValue(value); + } + + /** + * Add mapping. + * @param key The mapping's key. + * @value value The mapping's value + * @throws NullPointerException if key or value is null. + */ + public T put(CharSequence key, T value) throws NullPointerException + { + int len; + T old; + + if(key == null) + throw new NullPointerException("Null keys are not handled"); + if(value == null) + throw new NullPointerException("Null values are not handled"); + if(root == null) + root = new Node(); + if((old = root.put(key,0,value))!=null) + return old; + + // after in case of replacement + if((len = key.length()) > maxKeyLen) + maxKeyLen = len; + size++; + return null; + } + + /** + * Remove a entry. + * @return previous value + * @throws UnsupportedOperationException always. + */ + public T remove(Object key) throws UnsupportedOperationException + { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + public void putAll(Map map) + { + for(Map.Entry entry : map.entrySet()) + put(entry.getKey(),entry.getValue()); + } + + /** {@inheritDoc} */ + public Set keySet() + { + Set keys = new HashSet(size); + + if(root == null) + return keys; + return root.keySet(new StringBuilder(), keys); + } + + /** {@inheritDoc} */ + public Collection values() + { + ArrayList values = new ArrayList(size()); + + if(root == null) + return values; + return root.values(values); + } + + /** {@inheritDoc} */ + public Set> entrySet() + { + Set> entries = new HashSet>(size()); + + if(root == null) + return entries; + return root.entrySet(new StringBuilder(), entries); + } + + /** + * Get the value for a key. + * @param key The key to look up. + * @return The value for key or null if the key is not found. + */ + public T get(Object key) + { + if(root == null || key == null) + return null; + if(!(key instanceof CharSequence)) + return null; + return root.get((CharSequence)key,0); + } + + /** + * Get the number of entries. + * @return the number of entries. + */ + public int size() + { + return size; + } + + /** {@inheritDoc} */ + @Override + public boolean equals(Object other) + { + if(other == null) + return false; + if(!(other instanceof Map)) + return false; + // per spec + return entrySet().equals(((Map)other).entrySet()); + } + + /** {@inheritDoc} */ + @Override + public int hashCode() + { + // per spec + return entrySet().hashCode(); + } + + /** {@inheritDoc} */ + @Override + public String toString() + { + StringBuilder sb; + boolean first; + + if(isEmpty()) + return "{}"; + sb = new StringBuilder(); + first = true; + sb.append("{ "); + for(Map.Entry entry : entrySet()) + { + if(first) + first = false; + else + sb.append(", "); + sb.append(entry.toString()); + } + sb.append(" }"); + return sb.toString(); + } + + /** {@inheritDoc} */ + public boolean isEmpty() + { + return(size() == 0); + } +} diff --git a/src/main/java/org/owasp/esapi/codecs/Hex.java b/src/main/java/org/owasp/esapi/codecs/Hex.java new file mode 100644 index 000000000..5ca0b6890 --- /dev/null +++ b/src/main/java/org/owasp/esapi/codecs/Hex.java @@ -0,0 +1,84 @@ +/* + * 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) 2009 - The OWASP Foundation + */ +package org.owasp.esapi.codecs; + +/** Encode and decode to/from hexadecimal strings to byte arrays. */ +public class Hex { + + /** Output byte representation as hexadecimal representation. + * + * @param b Bytes to encode to hexadecimal representation. + * @param leading0x If true, return with leading "0x". + * @return Hexadecimal representation of specified bytes. + */ + public static String toHex(byte[] b, boolean leading0x) { + StringBuffer hexString = new StringBuffer(); + if ( leading0x ) { + hexString.append("0x"); + } + for ( int i = 0; i < b.length; i++ ) { + int j = b[i] & 0xff; // Convert byte to int. + String hex = Integer.toHexString(j); + if (hex.length() == 1) { + hexString.append('0'); // Add leading zero. + } + hexString.append(hex); // Hex digit(s). + } + return hexString.toString(); + } + + /** + * Output byte representation as hexadecimal representation. + * Alias for toHex() method. + * + * @param b Bytes to encode to hexadecimal representation. + * @param leading0x If true, return with leading "0x". + * @return Hexadecimal representation of specified bytes. + */ + public static String encode(byte[] b, boolean leading0x) { + return toHex(b, leading0x); + } + + /** + * Decode hexadecimal-encoded string and return raw byte array. + * Important note: This method preserves leading 0 filled bytes on the + * conversion process, which is important for cryptographic operations + * in dealing with things like keys, initialization vectors, etc. For + * example, the string "0x0000face" is going to return a byte array + * whose length is 4, not 2. + * + * @param hexStr Hexadecimal-encoded string, with or without leading "0x". + * @return The equivalent byte array. + */ + public static byte[] fromHex(String hexStr) { + String hexRep = hexStr; + if ( hexStr.startsWith("0x") ) { + // Then skip over the leading 0x. + hexRep = hexStr.substring(2); + } + int len = hexRep.length() / 2; + byte[] rawBytes = new byte[len]; + for (int i = 0; i < len; i++) { + String substr = hexRep.substring(i * 2, (i * 2) + 2); + rawBytes[i] = (byte)(Integer.parseInt(substr, 16)); + } + return rawBytes; + } + + /** Decode hexadecimal-encoded string and return raw byte array. + * Alias for fromHex() method. + * + * @param hexStr Hexadecimal-encoded string, with or without leading "0x". + * @return The equivalent byte array. + */ + public static byte[] decode(String hexStr) { + return fromHex(hexStr); + } +} diff --git a/src/main/java/org/owasp/esapi/codecs/JSONCodec.java b/src/main/java/org/owasp/esapi/codecs/JSONCodec.java new file mode 100644 index 000000000..524b2faac --- /dev/null +++ b/src/main/java/org/owasp/esapi/codecs/JSONCodec.java @@ -0,0 +1,245 @@ +/** + * 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) 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. + * + * @author Jeffrey Walton (noloader .at. gmail.com) + * @author Kevin Wall (kevin.w.wall .at. gmail.com) + * @author Matt Seil (matt.seil .at. owasp.org) + * @created 2022 + */ +package org.owasp.esapi.codecs; + +/** + * Implementation of the Codec interface for JSON strings. + * This class performs String escaping + * on the entire string according to RFC 8259, Section 7. + * + * RFC 8259 requires conforming implementations use UTF-8. However, the ESAPI interfaces + * utilize Java strings, which are UTF-16. This may cause problems during encoding and + * decoding operations. To avoid some of the problems, convert the string to UTF-8 before + * encoding and from UTF-8 after decoding. Ultimately the ESAPI encoder interfaces will + * need modification to provide byte array arguments and return values. + * + * @see RFC 8259, + * The JavaScript Object Notation (JSON) Data Interchange Format, Section 7 + * + * @author Jeffrey Walton (noloader .at. gmail.com) + * @author Kevin Wall (kevin.w.wall .at. gmail.com) + * @author Matt Seil (matt.seil .at. owasp.org) + * @since July 31, 2022 + * @see org.owasp.esapi.Encoder + */ +public class JSONCodec extends AbstractIntegerCodec { + + + /** + * {@inheritDoc} + * + * Escape special characters in JSON strings. + * + * encodeCharacter will escape the characters Backspace (\b), Form Feed (\f), + * Carriage Return (\r), Line Feed (\n), Tab (\t), Double Quote (") and Backslash (\). + * If the character is a control character (U+0000 through U+001f), then it will be + * Unicode encoded (\u0000 through \u001f). If the character is not special or in the + * user supplied immune list, then the character is returned unescaped. If the + * character is null then an empty string is returned. + * + * WARNING: This method will silently discard an invalid code point according to + * the result of {@code Character.isValidCodePoint( int )} method. + * + * @param immune character array of whitelist characters which should not be encoded + * @param c the character to encode if not in the immune list + * @return encoded character if the character is special, and the character otherwise. + */ + public String encodeCharacter( char[] immune, Character c ) { + if ( c == null ) { + return ""; + } + + return encodeCharacter(immune, charToCodepoint( c )); + } + + /** + * {@inheritDoc} + * + * Escape special characters in JSON strings. + * + * encodeCharacter will escape the characters Backspace (\b), Form Feed (\f), + * Carriage Return (\r), Line Feed (\n), Tab (\t), Double Quote (") and Backslash (\). + * If the character is a control character (U+0000 through U+001f), then it will be + * Unicode encoded (\u0000 through \u001f). If the character is not special or in the + * user supplied immune list, then the character is returned unescaped. If the + * character is null then an empty string is returned. + * + * WARNING: This method will silently discard an invalid code point according to + * the result of {@code Character.isValidCodePoint( int )} method. + * + * @param immune character array of whitelist characters which should not be encoded + * @param codePoint the character codepoint to encode if not in the immune list + * @return encoded character if the character is special, and the character otherwise. + */ + public String encodeCharacter( char[] immune, int codePoint ) + throws IllegalArgumentException { + + // Per the docs for HTMLEntityCodec: "WARNING: This method will silently discard + // invalid code points per the call to Character.isValidCodePoint( int ) method. + + // WARNING!! Character based Codecs will only handle the byte range of 0-65535 (0x0-0xffff). + // Passing any data represented by a higher numerical value will result in a downcast thus + // destroying the original data with undefined results. + if ( Character.isValidCodePoint( codePoint ) == false ) { + // throw new IllegalArgumentException( "Invalid codepoint '" + String.format("0x%04X", codePoint) + "'." ); + return ""; + } + + if ( immune != null ) { + // More efficient than sort and binary search. If the immune array + // was presorted, then this could be O(log n). But we can't add the + // precondition now. It is too late in the game. + for ( Character ch : immune ) { + if ( charToCodepoint( ch ) == codePoint ) { + return new String(Character.toChars(codePoint)); + } + } + } + + // Per the RFC... Two-character sequence escape representations of some + // popular characters + switch ( codePoint ) { + case '\b': return "\\b"; + case '\f': return "\\f"; + case '\r': return "\\r"; + case '\n': return "\\n"; + case '\t': return "\\t"; + case '"': return "\\\""; + case '/': return "\\/"; + case '\\': return "\\\\"; + } + + // Per the RFC... All Unicode characters may be placed within the + // quotation marks, except for the characters that MUST be escaped: + // quotation mark, reverse solidus, and the control characters + // (U+0000 through U+001F). + if ( codePoint <= 0x1f ) { + + return String.format("\\u%04x", codePoint); + } + + return new String(Character.toChars(codePoint)); + } + + + /** + * {@inheritDoc} + * + * Decodes special characters in encoded JSON strings. + * + * decodeCharacter will decode the encoded character sequences for popular characters + * Backspace (\b), Form Feed (\f), Carriage Return (\r), Line Feed (\n), Tab (\t), + * Double Quote ("), Forward slash (/) and Backslash (\). The function will also decode + * six-character sequences of \u0000 - \uffff. If the character is not encoded then a + * null character is returned. + * + * @param input a character sequence to decode + * @return the decoded version of the encoded character starting at index, + * or null otherwise + * + * @throws IllegalArgumentException + * if an invalid character sequence is encountered + */ + public Integer decodeCharacter( PushbackSequence input ) + throws IllegalArgumentException { + + input.mark(); + + Integer first = input.next(), second = null; + + //Ensure both first and second characters are not null before attempting to decode. + if ( first == null || first.intValue() != '\\' ) { + input.reset(); + return null; + } + if ( (second = input.next()) == null ) { + throw new IllegalArgumentException( "Invalid JSON escape representation"); + } + + Integer decodedRef = null; + + // Per the RFC... Two-character sequence escape representations of some popular characters + switch ( second.intValue() ) { + case 'b': + decodedRef = (int)'\b'; + break; + case 'f': + decodedRef = (int)'\f'; + break; + case 'r': + decodedRef = (int)'\r'; + break; + case 'n': + decodedRef = (int)'\n'; + break; + case 't': + decodedRef = (int)'\t'; + break; + case '"': + decodedRef = (int)'\"'; + break; + case '/': + decodedRef = (int)'/'; + break; + case '\\': + decodedRef = (int)'\\'; + break; + case 'u': + // Per the RFC... All characters may be escaped as a six-character sequence: a reverse solidus, + // followed by the lowercase letter u, followed by four hexadecimal digits that encode the + // character's code point. The hexadecimal letters A through F can be uppercase or lowercase. + // So, for example, a string containing only a single reverse solidus character may be represented + // as "\u005C". + decodedRef = (convertToInt( input.next() ) << 12) + + (convertToInt( input.next() ) << 8) + + (convertToInt( input.next() ) << 4) + + (convertToInt( input.next() ) << 0); + break; + default: + input.reset(); + throw new IllegalArgumentException( "Invalid JSON two-character escape representation: " + String.format("'%c%c'", (char) first.intValue(), (char) second.intValue()) ); + } + + return decodedRef; + } + + protected int charToCodepoint( Character ch ) { + + final String s = Character.toString(ch); + assert (s.length() == 1) : "Ooops"; + + return s.codePointAt(0); + } + + protected int convertToInt( Integer hexDigit ) { + + if ( hexDigit == null ) { + throw new IllegalArgumentException( "Cannot convert from '' to int." ); + } + + final int value = Character.digit( hexDigit.intValue(), 16 ); + + if ( value < 0 || value >= 16 ) { + throw new IllegalArgumentException( "Cannot convert from hexadecimal '" + hexDigit.toString() + "' to int." ); + } + + return value; + } + +} diff --git a/src/main/java/org/owasp/esapi/codecs/JavaScriptCodec.java b/src/main/java/org/owasp/esapi/codecs/JavaScriptCodec.java new file mode 100644 index 000000000..39f2d6406 --- /dev/null +++ b/src/main/java/org/owasp/esapi/codecs/JavaScriptCodec.java @@ -0,0 +1,220 @@ +/** + * 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.codecs; + + +/** + * Implementation of the Codec interface for backslash encoding in JavaScript. + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @since June 1, 2007 + * @see org.owasp.esapi.Encoder + */ +public class JavaScriptCodec extends AbstractCharacterCodec { + + + /** + * {@inheritDoc} + * + * Returns backslash encoded numeric format. Does not use backslash character escapes + * such as, \" or \' as these may cause parsing problems. For example, if a javascript + * attribute, such as onmouseover, contains a \" that will close the entire attribute and + * allow an attacker to inject another script attribute. + * + * @param immune + */ + public String encodeCharacter( char[] immune, Character c ) { + + // check for immune characters + if ( containsCharacter(c, immune ) ) { + return ""+c; + } + + // check for alphanumeric characters + String hex = super.getHexForNonAlphanumeric(c); + if ( hex == null ) { + return ""+c; + } + + // Do not use these shortcuts as they can be used to break out of a context + // if ( ch == 0x00 ) return "\\0"; + // if ( ch == 0x08 ) return "\\b"; + // if ( ch == 0x09 ) return "\\t"; + // if ( ch == 0x0a ) return "\\n"; + // if ( ch == 0x0b ) return "\\v"; + // if ( ch == 0x0c ) return "\\f"; + // if ( ch == 0x0d ) return "\\r"; + // if ( ch == 0x22 ) return "\\\""; + // if ( ch == 0x27 ) return "\\'"; + // if ( ch == 0x5c ) return "\\\\"; + + // encode up to 256 with \\xHH + String temp = Integer.toHexString(c); + if ( c < 256 ) { + String pad = "00".substring(temp.length() ); + return "\\x" + pad + temp.toUpperCase(); + } + + // otherwise encode with \\uHHHH + String pad = "0000".substring(temp.length() ); + return "\\u" + pad + temp.toUpperCase(); + } + + + /** + * {@inheritDoc} + * + * 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
+     *   \\OOO (1, 2, or 3 digits)
+     * 
+ */ + public Character decodeCharacter( PushbackSequence input ) { + input.mark(); + Character first = input.next(); + if ( first == null ) { + input.reset(); + return null; + } + + // if this is not an encoded character, return null + if (first != '\\' ) { + input.reset(); + return null; + } + + Character second = input.next(); + if ( second == null ) { + input.reset(); + return null; + } + + // \0 collides with the octal decoder and is non-standard + // if ( second.charValue() == '0' ) { + // return Character.valueOf( (char)0x00 ); + if (second == 'b' ) { + return 0x08; + } else if (second == 't' ) { + return 0x09; + } else if (second == 'n' ) { + return 0x0a; + } else if (second == 'v' ) { + return 0x0b; + } else if (second == 'f' ) { + return 0x0c; + } else if (second == 'r' ) { + return 0x0d; + } else if (second == '\"' ) { + return 0x22; + } else if (second == '\'' ) { + return 0x27; + } else if (second == '\\' ) { + return 0x5c; + + // look for \\xXX format + } else if ( Character.toLowerCase( second.charValue() ) == 'x' ) { + // Search for exactly 2 hex digits following + StringBuilder sb = new StringBuilder(); + for ( int i=0; i<2; i++ ) { + Character c = input.nextHex(); + if ( c != null ) sb.append( c ); + else { + input.reset(); + return null; + } + } + try { + // parse the hex digit and create a character + int i = Integer.parseInt(sb.toString(), 16); + if (Character.isValidCodePoint(i)) { + return (char) i; + } + } catch( NumberFormatException e ) { + // throw an exception for malformed entity? + input.reset(); + return null; + } + + // look for \\uXXXX format + } else if ( Character.toLowerCase( second.charValue() ) == 'u') { + // Search for exactly 4 hex digits following + StringBuilder sb = new StringBuilder(); + for ( int i=0; i<4; i++ ) { + Character c = input.nextHex(); + if ( c != null ) sb.append( c ); + else { + input.reset(); + return null; + } + } + try { + // parse the hex string and create a character + int i = Integer.parseInt(sb.toString(), 16); + if (Character.isValidCodePoint(i)) { + return (char) i; + } + } catch( NumberFormatException e ) { + // throw an exception for malformed entity? + input.reset(); + return null; + } + + // look for one, two, or three octal digits + } else if ( PushbackString.isOctalDigit(second) ) { + StringBuilder sb = new StringBuilder(); + // get digit 1 + sb.append(second); + + // get digit 2 if present + Character c2 = input.next(); + if ( !PushbackString.isOctalDigit(c2) ) { + input.pushback( c2 ); + } else { + sb.append( c2 ); + // get digit 3 if present + Character c3 = input.next(); + if ( !PushbackString.isOctalDigit(c3) ) { + input.pushback( c3 ); + } else { + sb.append( c3 ); + } + } + try { + // parse the octal string and create a character + int i = Integer.parseInt(sb.toString(), 8); + if (Character.isValidCodePoint(i)) { + return (char) i; + } + } catch( NumberFormatException e ) { + // throw an exception for malformed entity? + input.reset(); + return null; + } + } + + // ignore the backslash and return the character + input.reset(); + return null; + } + +} diff --git a/src/main/java/org/owasp/esapi/codecs/LegacyHTMLEntityCodec.java b/src/main/java/org/owasp/esapi/codecs/LegacyHTMLEntityCodec.java new file mode 100644 index 000000000..240cc2ca7 --- /dev/null +++ b/src/main/java/org/owasp/esapi/codecs/LegacyHTMLEntityCodec.java @@ -0,0 +1,557 @@ +/** + * 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.codecs; + +import java.util.HashMap; +import java.util.Collections; +import java.util.Map; + +/** + * + * This class is DEPRECATED. It did not correctly handle encoding of non-BMP + * unicode code points. This class is provided solely for any fatal bugs + * not accounted for in the new version and will be removed entirely in + * a future release. + * + * Implementation of the Codec interface for HTML entity encoding. + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @since June 1, 2007 + * @see org.owasp.esapi.Encoder + */ +@Deprecated +public class LegacyHTMLEntityCodec extends AbstractCharacterCodec { + + private static final char REPLACEMENT_CHAR = '\ufffd'; + private static final String REPLACEMENT_HEX = "fffd"; + private static final String REPLACEMENT_STR = "" + REPLACEMENT_CHAR; + private static final Map characterToEntityMap = mkCharacterToEntityMap(); + private static final Trie entityToCharacterTrie = mkEntityToCharacterTrie(); + + /** + * {@inheritDoc} + * + * Encodes a Character for safe use in an HTML entity field. + * @param immune + */ + public String encodeCharacter( char[] immune, Character c ) { + + // check for immune characters + if ( containsCharacter(c, immune ) ) { + return ""+c; + } + + // check for alphanumeric characters + String hex = super.getHexForNonAlphanumeric(c); + if ( hex == null ) { + return ""+c; + } + + // check for illegal characters + if ( ( c <= 0x1f && c != '\t' && c != '\n' && c != '\r' ) || ( c >= 0x7f && c <= 0x9f ) ) + { + hex = REPLACEMENT_HEX; // Let's entity encode this instead of returning it + c = REPLACEMENT_CHAR; + } + + // check if there's a defined entity + String entityName = characterToEntityMap.get(c); + if (entityName != null) { + return "&" + entityName + ";"; + } + + // return the hex entity as suggested in the spec + return "&#x" + hex + ";"; + } + + /** + * 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; + * &#xhhhh; + * &name; + */ + public Character decodeCharacter( PushbackString input ) { + input.mark(); + Character first = input.next(); + if ( first == null ) { + input.reset(); + return null; + } + + // if this is not an encoded character, return null + if (first != '&' ) { + input.reset(); + return null; + } + + // test for numeric encodings + Character second = input.next(); + if ( second == null ) { + input.reset(); + return null; + } + + if (second == '#' ) { + // handle numbers + Character c = getNumericEntity( input ); + if ( c != null ) return c; + } else if ( Character.isLetter( second.charValue() ) ) { + // handle entities + input.pushback( second ); + Character c = getNamedEntity( input ); + if ( c != null ) return c; + } + input.reset(); + return null; + } + + /** + * getNumericEntry checks input to see if it is a numeric entity + * + * @param input + * The input to test for being a numeric entity + * + * @return + * null if input is null, the character of input after decoding + */ + private Character getNumericEntity( PushbackString input ) { + Character first = input.peek(); + if ( first == null ) return null; + + if (first == 'x' || first == 'X' ) { + input.next(); + return parseHex( input ); + } + return parseNumber( input ); + } + + /** + * Parse a decimal number, such as those from JavaScript's String.fromCharCode(value) + * + * @param input + * decimal encoded string, such as 65 + * @return + * character representation of this decimal value, e.g. A + * @throws NumberFormatException + */ + private Character parseNumber( PushbackString input ) { + StringBuilder sb = new StringBuilder(); + while( input.hasNext() ) { + Character c = input.peek(); + + // if character is a digit then add it on and keep going + if ( Character.isDigit( c.charValue() ) ) { + sb.append( c ); + input.next(); + + // if character is a semi-colon, eat it and quit + } else if (c == ';' ) { + input.next(); + break; + + // otherwise just quit + } else { + break; + } + } + try { + int i = Integer.parseInt(sb.toString()); + if (Character.isValidCodePoint(i)) { + return (char) i; + } + } catch( NumberFormatException e ) { + // throw an exception for malformed entity? + } + return null; + } + + /** + * Parse a hex encoded entity + * + * @param input + * Hex encoded input (such as 437ae;) + * @return + * A single character from the string + * @throws NumberFormatException + */ + private Character parseHex( PushbackString input ) { + StringBuilder sb = new StringBuilder(); + while( input.hasNext() ) { + Character c = input.peek(); + + // if character is a hex digit then add it on and keep going + if ( "0123456789ABCDEFabcdef".indexOf(c) != -1 ) { + sb.append( c ); + input.next(); + + // if character is a semi-colon, eat it and quit + } else if (c == ';' ) { + input.next(); + break; + + // otherwise just quit + } else { + break; + } + } + try { + int i = Integer.parseInt(sb.toString(), 16); + if (Character.isValidCodePoint(i)) { + return (char) i; + } + } catch( NumberFormatException e ) { + // throw an exception for malformed entity? + } + return null; + } + + /** + * + * 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: + * &aa; + * &aaa; + * &aaaa; + * &aaaaa; + * &aaaaaa; + * &aaaaaaa; + * + * @param input + * A string containing a named entity like " + * @return + * Returns the decoded version of the character starting at index, or null if no decoding is possible. + */ + private Character getNamedEntity( PushbackString input ) { + StringBuilder possible = new StringBuilder(); + Map.Entry entry; + int len; + + // kludge around PushbackString.... + len = Math.min(input.remainder().length(), entityToCharacterTrie.getMaxKeyLength()); + for(int i=0;i exactEntry = entityToCharacterTrie.getLongestMatch(possibleStringLowerCase); + if(exactEntry != null) entry = exactEntry; + } + if(entry == null) return null; // no match, caller will reset input + } + + // fixup input + input.reset(); + input.next(); // read & + len = entry.getKey().length(); // what matched's length + for(int i=0;i mkCharacterToEntityMap() + { + Map map = new HashMap(252); + + map.put((char)34, "quot"); /* quotation mark */ + map.put((char)38, "amp"); /* ampersand */ + map.put((char)60, "lt"); /* less-than sign */ + map.put((char)62, "gt"); /* greater-than sign */ + map.put((char)160, "nbsp"); /* no-break space */ + map.put((char)161, "iexcl"); /* inverted exclamation mark */ + map.put((char)162, "cent"); /* cent sign */ + map.put((char)163, "pound"); /* pound sign */ + map.put((char)164, "curren"); /* currency sign */ + map.put((char)165, "yen"); /* yen sign */ + map.put((char)166, "brvbar"); /* broken bar */ + map.put((char)167, "sect"); /* section sign */ + map.put((char)168, "uml"); /* diaeresis */ + map.put((char)169, "copy"); /* copyright sign */ + map.put((char)170, "ordf"); /* feminine ordinal indicator */ + map.put((char)171, "laquo"); /* left-pointing double angle quotation mark */ + map.put((char)172, "not"); /* not sign */ + map.put((char)173, "shy"); /* soft hyphen */ + map.put((char)174, "reg"); /* registered sign */ + map.put((char)175, "macr"); /* macron */ + map.put((char)176, "deg"); /* degree sign */ + map.put((char)177, "plusmn"); /* plus-minus sign */ + map.put((char)178, "sup2"); /* superscript two */ + map.put((char)179, "sup3"); /* superscript three */ + map.put((char)180, "acute"); /* acute accent */ + map.put((char)181, "micro"); /* micro sign */ + map.put((char)182, "para"); /* pilcrow sign */ + map.put((char)183, "middot"); /* middle dot */ + map.put((char)184, "cedil"); /* cedilla */ + map.put((char)185, "sup1"); /* superscript one */ + map.put((char)186, "ordm"); /* masculine ordinal indicator */ + map.put((char)187, "raquo"); /* right-pointing double angle quotation mark */ + map.put((char)188, "frac14"); /* vulgar fraction one quarter */ + map.put((char)189, "frac12"); /* vulgar fraction one half */ + map.put((char)190, "frac34"); /* vulgar fraction three quarters */ + map.put((char)191, "iquest"); /* inverted question mark */ + map.put((char)192, "Agrave"); /* Latin capital letter a with grave */ + map.put((char)193, "Aacute"); /* Latin capital letter a with acute */ + map.put((char)194, "Acirc"); /* Latin capital letter a with circumflex */ + map.put((char)195, "Atilde"); /* Latin capital letter a with tilde */ + map.put((char)196, "Auml"); /* Latin capital letter a with diaeresis */ + map.put((char)197, "Aring"); /* Latin capital letter a with ring above */ + map.put((char)198, "AElig"); /* Latin capital letter ae */ + map.put((char)199, "Ccedil"); /* Latin capital letter c with cedilla */ + map.put((char)200, "Egrave"); /* Latin capital letter e with grave */ + map.put((char)201, "Eacute"); /* Latin capital letter e with acute */ + map.put((char)202, "Ecirc"); /* Latin capital letter e with circumflex */ + map.put((char)203, "Euml"); /* Latin capital letter e with diaeresis */ + map.put((char)204, "Igrave"); /* Latin capital letter i with grave */ + map.put((char)205, "Iacute"); /* Latin capital letter i with acute */ + map.put((char)206, "Icirc"); /* Latin capital letter i with circumflex */ + map.put((char)207, "Iuml"); /* Latin capital letter i with diaeresis */ + map.put((char)208, "ETH"); /* Latin capital letter eth */ + map.put((char)209, "Ntilde"); /* Latin capital letter n with tilde */ + map.put((char)210, "Ograve"); /* Latin capital letter o with grave */ + map.put((char)211, "Oacute"); /* Latin capital letter o with acute */ + map.put((char)212, "Ocirc"); /* Latin capital letter o with circumflex */ + map.put((char)213, "Otilde"); /* Latin capital letter o with tilde */ + map.put((char)214, "Ouml"); /* Latin capital letter o with diaeresis */ + map.put((char)215, "times"); /* multiplication sign */ + map.put((char)216, "Oslash"); /* Latin capital letter o with stroke */ + map.put((char)217, "Ugrave"); /* Latin capital letter u with grave */ + map.put((char)218, "Uacute"); /* Latin capital letter u with acute */ + map.put((char)219, "Ucirc"); /* Latin capital letter u with circumflex */ + map.put((char)220, "Uuml"); /* Latin capital letter u with diaeresis */ + map.put((char)221, "Yacute"); /* Latin capital letter y with acute */ + map.put((char)222, "THORN"); /* Latin capital letter thorn */ + map.put((char)223, "szlig"); /* Latin small letter sharp sXCOMMAX German Eszett */ + map.put((char)224, "agrave"); /* Latin small letter a with grave */ + map.put((char)225, "aacute"); /* Latin small letter a with acute */ + map.put((char)226, "acirc"); /* Latin small letter a with circumflex */ + map.put((char)227, "atilde"); /* Latin small letter a with tilde */ + map.put((char)228, "auml"); /* Latin small letter a with diaeresis */ + map.put((char)229, "aring"); /* Latin small letter a with ring above */ + map.put((char)230, "aelig"); /* Latin lowercase ligature ae */ + map.put((char)231, "ccedil"); /* Latin small letter c with cedilla */ + map.put((char)232, "egrave"); /* Latin small letter e with grave */ + map.put((char)233, "eacute"); /* Latin small letter e with acute */ + map.put((char)234, "ecirc"); /* Latin small letter e with circumflex */ + map.put((char)235, "euml"); /* Latin small letter e with diaeresis */ + map.put((char)236, "igrave"); /* Latin small letter i with grave */ + map.put((char)237, "iacute"); /* Latin small letter i with acute */ + map.put((char)238, "icirc"); /* Latin small letter i with circumflex */ + map.put((char)239, "iuml"); /* Latin small letter i with diaeresis */ + map.put((char)240, "eth"); /* Latin small letter eth */ + map.put((char)241, "ntilde"); /* Latin small letter n with tilde */ + map.put((char)242, "ograve"); /* Latin small letter o with grave */ + map.put((char)243, "oacute"); /* Latin small letter o with acute */ + map.put((char)244, "ocirc"); /* Latin small letter o with circumflex */ + map.put((char)245, "otilde"); /* Latin small letter o with tilde */ + map.put((char)246, "ouml"); /* Latin small letter o with diaeresis */ + map.put((char)247, "divide"); /* division sign */ + map.put((char)248, "oslash"); /* Latin small letter o with stroke */ + map.put((char)249, "ugrave"); /* Latin small letter u with grave */ + map.put((char)250, "uacute"); /* Latin small letter u with acute */ + map.put((char)251, "ucirc"); /* Latin small letter u with circumflex */ + map.put((char)252, "uuml"); /* Latin small letter u with diaeresis */ + map.put((char)253, "yacute"); /* Latin small letter y with acute */ + map.put((char)254, "thorn"); /* Latin small letter thorn */ + map.put((char)255, "yuml"); /* Latin small letter y with diaeresis */ + map.put((char)338, "OElig"); /* Latin capital ligature oe */ + map.put((char)339, "oelig"); /* Latin small ligature oe */ + map.put((char)352, "Scaron"); /* Latin capital letter s with caron */ + map.put((char)353, "scaron"); /* Latin small letter s with caron */ + map.put((char)376, "Yuml"); /* Latin capital letter y with diaeresis */ + map.put((char)402, "fnof"); /* Latin small letter f with hook */ + map.put((char)710, "circ"); /* modifier letter circumflex accent */ + map.put((char)732, "tilde"); /* small tilde */ + map.put((char)913, "Alpha"); /* Greek capital letter alpha */ + map.put((char)914, "Beta"); /* Greek capital letter beta */ + map.put((char)915, "Gamma"); /* Greek capital letter gamma */ + map.put((char)916, "Delta"); /* Greek capital letter delta */ + map.put((char)917, "Epsilon"); /* Greek capital letter epsilon */ + map.put((char)918, "Zeta"); /* Greek capital letter zeta */ + map.put((char)919, "Eta"); /* Greek capital letter eta */ + map.put((char)920, "Theta"); /* Greek capital letter theta */ + map.put((char)921, "Iota"); /* Greek capital letter iota */ + map.put((char)922, "Kappa"); /* Greek capital letter kappa */ + map.put((char)923, "Lambda"); /* Greek capital letter lambda */ + map.put((char)924, "Mu"); /* Greek capital letter mu */ + map.put((char)925, "Nu"); /* Greek capital letter nu */ + map.put((char)926, "Xi"); /* Greek capital letter xi */ + map.put((char)927, "Omicron"); /* Greek capital letter omicron */ + map.put((char)928, "Pi"); /* Greek capital letter pi */ + map.put((char)929, "Rho"); /* Greek capital letter rho */ + map.put((char)931, "Sigma"); /* Greek capital letter sigma */ + map.put((char)932, "Tau"); /* Greek capital letter tau */ + map.put((char)933, "Upsilon"); /* Greek capital letter upsilon */ + map.put((char)934, "Phi"); /* Greek capital letter phi */ + map.put((char)935, "Chi"); /* Greek capital letter chi */ + map.put((char)936, "Psi"); /* Greek capital letter psi */ + map.put((char)937, "Omega"); /* Greek capital letter omega */ + map.put((char)945, "alpha"); /* Greek small letter alpha */ + map.put((char)946, "beta"); /* Greek small letter beta */ + map.put((char)947, "gamma"); /* Greek small letter gamma */ + map.put((char)948, "delta"); /* Greek small letter delta */ + map.put((char)949, "epsilon"); /* Greek small letter epsilon */ + map.put((char)950, "zeta"); /* Greek small letter zeta */ + map.put((char)951, "eta"); /* Greek small letter eta */ + map.put((char)952, "theta"); /* Greek small letter theta */ + map.put((char)953, "iota"); /* Greek small letter iota */ + map.put((char)954, "kappa"); /* Greek small letter kappa */ + map.put((char)955, "lambda"); /* Greek small letter lambda */ + map.put((char)956, "mu"); /* Greek small letter mu */ + map.put((char)957, "nu"); /* Greek small letter nu */ + map.put((char)958, "xi"); /* Greek small letter xi */ + map.put((char)959, "omicron"); /* Greek small letter omicron */ + map.put((char)960, "pi"); /* Greek small letter pi */ + map.put((char)961, "rho"); /* Greek small letter rho */ + map.put((char)962, "sigmaf"); /* Greek small letter final sigma */ + map.put((char)963, "sigma"); /* Greek small letter sigma */ + map.put((char)964, "tau"); /* Greek small letter tau */ + map.put((char)965, "upsilon"); /* Greek small letter upsilon */ + map.put((char)966, "phi"); /* Greek small letter phi */ + map.put((char)967, "chi"); /* Greek small letter chi */ + map.put((char)968, "psi"); /* Greek small letter psi */ + map.put((char)969, "omega"); /* Greek small letter omega */ + map.put((char)977, "thetasym"); /* Greek theta symbol */ + map.put((char)978, "upsih"); /* Greek upsilon with hook symbol */ + map.put((char)982, "piv"); /* Greek pi symbol */ + map.put((char)8194, "ensp"); /* en space */ + map.put((char)8195, "emsp"); /* em space */ + map.put((char)8201, "thinsp"); /* thin space */ + map.put((char)8204, "zwnj"); /* zero width non-joiner */ + map.put((char)8205, "zwj"); /* zero width joiner */ + map.put((char)8206, "lrm"); /* left-to-right mark */ + map.put((char)8207, "rlm"); /* right-to-left mark */ + map.put((char)8211, "ndash"); /* en dash */ + map.put((char)8212, "mdash"); /* em dash */ + map.put((char)8216, "lsquo"); /* left single quotation mark */ + map.put((char)8217, "rsquo"); /* right single quotation mark */ + map.put((char)8218, "sbquo"); /* single low-9 quotation mark */ + map.put((char)8220, "ldquo"); /* left double quotation mark */ + map.put((char)8221, "rdquo"); /* right double quotation mark */ + map.put((char)8222, "bdquo"); /* double low-9 quotation mark */ + map.put((char)8224, "dagger"); /* dagger */ + map.put((char)8225, "Dagger"); /* double dagger */ + map.put((char)8226, "bull"); /* bullet */ + map.put((char)8230, "hellip"); /* horizontal ellipsis */ + map.put((char)8240, "permil"); /* per mille sign */ + map.put((char)8242, "prime"); /* prime */ + map.put((char)8243, "Prime"); /* double prime */ + map.put((char)8249, "lsaquo"); /* single left-pointing angle quotation mark */ + map.put((char)8250, "rsaquo"); /* single right-pointing angle quotation mark */ + map.put((char)8254, "oline"); /* overline */ + map.put((char)8260, "frasl"); /* fraction slash */ + map.put((char)8364, "euro"); /* euro sign */ + map.put((char)8465, "image"); /* black-letter capital i */ + map.put((char)8472, "weierp"); /* script capital pXCOMMAX Weierstrass p */ + map.put((char)8476, "real"); /* black-letter capital r */ + map.put((char)8482, "trade"); /* trademark sign */ + map.put((char)8501, "alefsym"); /* alef symbol */ + map.put((char)8592, "larr"); /* leftwards arrow */ + map.put((char)8593, "uarr"); /* upwards arrow */ + map.put((char)8594, "rarr"); /* rightwards arrow */ + map.put((char)8595, "darr"); /* downwards arrow */ + map.put((char)8596, "harr"); /* left right arrow */ + map.put((char)8629, "crarr"); /* downwards arrow with corner leftwards */ + map.put((char)8656, "lArr"); /* leftwards double arrow */ + map.put((char)8657, "uArr"); /* upwards double arrow */ + map.put((char)8658, "rArr"); /* rightwards double arrow */ + map.put((char)8659, "dArr"); /* downwards double arrow */ + map.put((char)8660, "hArr"); /* left right double arrow */ + map.put((char)8704, "forall"); /* for all */ + map.put((char)8706, "part"); /* partial differential */ + map.put((char)8707, "exist"); /* there exists */ + map.put((char)8709, "empty"); /* empty set */ + map.put((char)8711, "nabla"); /* nabla */ + map.put((char)8712, "isin"); /* element of */ + map.put((char)8713, "notin"); /* not an element of */ + map.put((char)8715, "ni"); /* contains as member */ + map.put((char)8719, "prod"); /* n-ary product */ + map.put((char)8721, "sum"); /* n-ary summation */ + map.put((char)8722, "minus"); /* minus sign */ + map.put((char)8727, "lowast"); /* asterisk operator */ + map.put((char)8730, "radic"); /* square root */ + map.put((char)8733, "prop"); /* proportional to */ + map.put((char)8734, "infin"); /* infinity */ + map.put((char)8736, "ang"); /* angle */ + map.put((char)8743, "and"); /* logical and */ + map.put((char)8744, "or"); /* logical or */ + map.put((char)8745, "cap"); /* intersection */ + map.put((char)8746, "cup"); /* union */ + map.put((char)8747, "int"); /* integral */ + map.put((char)8756, "there4"); /* therefore */ + map.put((char)8764, "sim"); /* tilde operator */ + map.put((char)8773, "cong"); /* congruent to */ + map.put((char)8776, "asymp"); /* almost equal to */ + map.put((char)8800, "ne"); /* not equal to */ + map.put((char)8801, "equiv"); /* identical toXCOMMAX equivalent to */ + map.put((char)8804, "le"); /* less-than or equal to */ + map.put((char)8805, "ge"); /* greater-than or equal to */ + map.put((char)8834, "sub"); /* subset of */ + map.put((char)8835, "sup"); /* superset of */ + map.put((char)8836, "nsub"); /* not a subset of */ + map.put((char)8838, "sube"); /* subset of or equal to */ + map.put((char)8839, "supe"); /* superset of or equal to */ + map.put((char)8853, "oplus"); /* circled plus */ + map.put((char)8855, "otimes"); /* circled times */ + map.put((char)8869, "perp"); /* up tack */ + map.put((char)8901, "sdot"); /* dot operator */ + map.put((char)8968, "lceil"); /* left ceiling */ + map.put((char)8969, "rceil"); /* right ceiling */ + map.put((char)8970, "lfloor"); /* left floor */ + map.put((char)8971, "rfloor"); /* right floor */ + map.put((char)9001, "lang"); /* left-pointing angle bracket */ + map.put((char)9002, "rang"); /* right-pointing angle bracket */ + map.put((char)9674, "loz"); /* lozenge */ + map.put((char)9824, "spades"); /* black spade suit */ + map.put((char)9827, "clubs"); /* black club suit */ + map.put((char)9829, "hearts"); /* black heart suit */ + map.put((char)9830, "diams"); /* black diamond suit */ + + return Collections.unmodifiableMap(map); + } + + /** + * Build a unmodifiable Trie from entitiy Name to Character + * @return Unmodifiable trie. + */ + private static synchronized Trie mkEntityToCharacterTrie() + { + Trie trie = new HashTrie(); + + for(Map.Entry entry : characterToEntityMap.entrySet()) + trie.put(entry.getValue(),entry.getKey()); + return Trie.Util.unmodifiable(trie); + } +} diff --git a/src/main/java/org/owasp/esapi/codecs/MySQLCodec.java b/src/main/java/org/owasp/esapi/codecs/MySQLCodec.java new file mode 100644 index 000000000..bd2829521 --- /dev/null +++ b/src/main/java/org/owasp/esapi/codecs/MySQLCodec.java @@ -0,0 +1,314 @@ +/** + * 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.codecs; + + + +/** + * Codec implementation which can be used to escape string literals in MySQL. + * This function will only protect you from SQLi in limited situations. + * To improve your chances of success, you made also need to do some + * additional canonicalization and input validation first. Before using this class, + * please be sure to read the "SECURITY WARNING" in + * {@link org.owasp.esapi.Encoder#encodeForSQL} + * before using this particular {@link org.owasp.esapi.codecs.Codec} and raising your hope of finding + * a silver bullet to kill all the SQLi werewolves. + *

+ * This implementation accepts 2 {@code org.owasp.esapi.codes.MySQLCodec.Mode}s as identified + * by the OWASP recommended escaping strategies: + *

    + *
  • ANSI
    + * Simply encode all ' (single tick) characters with '' (two single ticks)
  • + *
    + *
  • Standard + * + *
    + *   NUL (0x00) --> \0  [This is a zero, not the letter O]
    + *   BS  (0x08) --> \b
    + *   TAB (0x09) --> \t
    + *   LF  (0x0a) --> \n
    + *   CR  (0x0d) --> \r
    + *   SUB (0x1a) --> \Z
    + *   "   (0x22) --> \"
    + *   %   (0x25) --> \%
    + *   '   (0x27) --> \'
    + *   \   (0x5c) --> \\
    + *   _   (0x5f) --> \_
    + *   
    + * all other non-alphanumeric characters with ASCII values less than 256 --> \c + * where 'c' is the original non-alphanumeric character. + *
    + * + *
  • + * + *
+ * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) + * Aspect Security + * @since June 1, 2007 + * + * MySQL 8.0 String Literals + * OWASP + * SQL_Injection_Prevention_Cheat_Sheet#MySQL_Escaping + * @see + * ESAPI Security Bulletin #13 + * @deprecated This class 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 +public class MySQLCodec extends AbstractCharacterCodec { + /** + * Specifies the SQL Mode the target MySQL Server is running with. For details about MySQL Server Modes + * please see the Manual at + * @link http://dev.mysql.com/doc/refman/5.0/en/server-sql-mode.html#sqlmode_ansi + * + * Currently, the only supported modes are: + * ANSI + * STANDARD + */ + public static enum Mode { + ANSI(1),STANDARD(0); + + private int key; + private Mode(int key) { this.key = key; } + + static Mode findByKey(int key) { + for ( Mode m : values() ) { + if ( m.key == key ) + return m; + } + String message = String.format("No Mode for %s. Valid references are MySQLStandard: %s or ANSI: %s", key, MYSQL_MODE, ANSI_MODE); + throw new IllegalArgumentException(message); + } + } + + /** Target MySQL Server is running in Standard MySQL (Default) mode. */ + public static final int MYSQL_MODE = 0; + + /** + * Target MySQL Server is running in ANSI_QUOTES Mode + * + * @see + * https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html#sqlmode_ansi_quotes + */ + public static final int ANSI_MODE = 1; + + //private int mode = 0; + private Mode mode; + + /** + * Instantiate the MySQL codec + * + * @param mode + * Mode has to be one of {MYSQL_MODE|ANSI_MODE} to allow correct encoding + * @deprecated + * @see #MySQLCodec(org.owasp.esapi.codecs.MySQLCodec.Mode) + */ + @Deprecated + public MySQLCodec( int mode ) { + this.mode = Mode.findByKey(mode); + } + + /** + * Instantiate the MySQL Codec with the given SQL {@link Mode}. + * @param mode The mode the target server is running in + */ + public MySQLCodec( Mode mode ) { + this.mode = mode; + } + + + /** + * {@inheritDoc} + */ + public String encodeCharacter( char[] immune, Character c ) { + char ch = c.charValue(); + + // check for immune characters + if ( containsCharacter( ch, immune ) ) { + return ""+ch; + } + + // check for alphanumeric characters + String hex = super.getHexForNonAlphanumeric( ch ); + if ( hex == null ) { + return ""+ch; + } + + + switch( mode ) { + case ANSI: return encodeCharacterANSI( c ); + case STANDARD: return encodeCharacterMySQL( c ); + default: return null; + } + } + + /** + * encodeCharacterANSI encodes for ANSI SQL. + * + * Apostrophe is encoded + * + * Bug ###: In ANSI Mode Strings can also be passed in using the quotation. In ANSI_QUOTES mode a quotation + * is considered to be an identifier, thus cannot be used at all in a value and will be dropped completely. + * + * @param c + * character to encode + * @return + * String encoded to standards of MySQL running in ANSI mode + */ + private String encodeCharacterANSI( Character c ) { + if ( c == '\'' ) + return "\'\'"; + + return ""+c; + } + + /** + * Encode a character suitable for MySQL + * + * @param c + * Character to encode + * @return + * Encoded Character + */ + private String encodeCharacterMySQL( Character c ) { + char ch = c.charValue(); + if ( ch == 0x00 ) return "\\0"; + if ( ch == 0x08 ) return "\\b"; + if ( ch == 0x09 ) return "\\t"; + if ( ch == 0x0a ) return "\\n"; + if ( ch == 0x0d ) return "\\r"; + if ( ch == 0x1a ) return "\\Z"; + if ( ch == 0x22 ) return "\\\""; + if ( ch == 0x25 ) return "\\%"; + if ( ch == 0x27 ) return "\\'"; + if ( ch == 0x5c ) return "\\\\"; + if ( ch == 0x5f ) return "\\_"; + return "\\" + c; + } + + /** + * {@inheritDoc} + * + * 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) + */ + public Character decodeCharacter( PushbackSequence input ) { + switch( mode ) { + case ANSI: return decodeCharacterANSI( input ); + case STANDARD: return decodeCharacterMySQL( input ); + default: return null; + } + } + + /** + * decodeCharacterANSI decodes the next character from ANSI SQL escaping + * + * @param input + * A PushBackString containing characters you'd like decoded + * @return + * A single character, decoded + */ + private Character decodeCharacterANSI( PushbackSequence input ) { + input.mark(); + Character first = input.next(); + if ( first == null ) { + input.reset(); + return null; + } + + // if this is not an encoded character, return null + if ( first.charValue() != '\'' ) { + input.reset(); + return null; + } + + Character second = input.next(); + if ( second == null ) { + input.reset(); + return null; + } + + // if this is not an encoded character, return null + if ( second.charValue() != '\'' ) { + input.reset(); + return null; + } + return( Character.valueOf( '\'' ) ); + } + + /** + * decodeCharacterMySQL decodes all the potential escaped characters that MySQL is prepared to escape + * + * @param input + * A string you'd like to be decoded + * @return + * A single character from that string, decoded. + */ + private Character decodeCharacterMySQL( PushbackSequence input ) { + input.mark(); + Character first = input.next(); + if ( first == null ) { + input.reset(); + return null; + } + + // if this is not an encoded character, return null + if ( first.charValue() != '\\' ) { + input.reset(); + return null; + } + + Character second = input.next(); + if ( second == null ) { + input.reset(); + return null; + } + + if ( second.charValue() == '0' ) { + return Character.valueOf( (char)0x00 ); + } else if ( second.charValue() == 'b' ) { + return Character.valueOf( (char)0x08 ); + } else if ( second.charValue() == 't' ) { + return Character.valueOf( (char)0x09 ); + } else if ( second.charValue() == 'n' ) { + return Character.valueOf( (char)0x0a ); + } else if ( second.charValue() == 'r' ) { + return Character.valueOf( (char)0x0d ); + } else if ( second.charValue() == 'Z' ) { + return Character.valueOf( (char)0x1a ); + } else if ( second.charValue() == '\"' ) { + return Character.valueOf( (char)0x22 ); + } else if ( second.charValue() == '%' ) { + return Character.valueOf( (char)0x25 ); + } else if ( second.charValue() == '\'' ) { + return Character.valueOf( (char)0x27 ); + } else if ( second.charValue() == '\\' ) { + return Character.valueOf( (char)0x5c ); + } else if ( second.charValue() == '_' ) { + return Character.valueOf( (char)0x5f ); + } else { + return second; + } + } + +} diff --git a/src/main/java/org/owasp/esapi/codecs/OracleCodec.java b/src/main/java/org/owasp/esapi/codecs/OracleCodec.java new file mode 100644 index 000000000..2746f9137 --- /dev/null +++ b/src/main/java/org/owasp/esapi/codecs/OracleCodec.java @@ -0,0 +1,118 @@ +/** + * 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.codecs; + + + +/** + * Implementation of the {@link org.owasp.esapi.codecs.Codec} interface for Oracle DB strings. + * This function will only protect you from SQLi in limited situations. + * To improve your chances of success, you may also need to do some + * additional canonicalization and input validation first. Before using this class, + * please be sure to read the "SECURITY WARNING" in + * {@link org.owasp.esapi.Encoder#encodeForSQL} + * before using this particular {@link org.owasp.esapi.codecs.Codec} and raising your hope of finding + * a silver bullet to kill all the SQLi werewolves. + *

+ * CAUTION: This class has some known issues. During the investigation of + * CVE-2025-5878, it was discovered that since this class' inception in + * 2007, that Oracle databases also use \ (backslash) as a default escape char. + * That was fundamental in the vulnerability, since the escape character itself + * was not being escaped. We had originally planned to address this, but while + * researching the issue, we discovered that not only was there a new default + * escape character for Oracle SQL*Plus, but that developers could actually + * override the default to a character of their choosing. (For details see + * SET ESCAPE + * and + * How to Escape Characters in Oracle PL/SQL Queries.) The second instance is + * especially scary, since it illustrates how a developer can potentially can + * the default escape character as part of an ordinary SQL statement. We + * realized that there is no way we can defend against this, so it seemed + * pointless to even bother to try to quote default escape character passed in + * as input when {@code OracleCodec} is used with the {@code Encoder.encodeForSQL} + * interface. Therefore, you really should not use this, but if dead set in + * still using this leg canon, it;s on you. You have been warned. + *

+ * @see org.owasp.esapi.Encoder + * @see + * ESAPI Security Bulletin #13 + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @author Jim Manico (jim@manico.net) Manico.net + * @since June 1, 2007 + * @see how-to-escape-single-quotes-in-strings + * @deprecated This class 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 +public class OracleCodec extends AbstractCharacterCodec { + + + /** + * {@inheritDoc} + * + * Encodes ' to '' + * + * Encodes ' to '' + * + * @param immune + */ + public String encodeCharacter( char[] immune, Character c ) { + if ( c.charValue() == '\'' ) + return "\'\'"; + return ""+c; + } + + + + /** + * {@inheritDoc} + * + * Returns the decoded version of the character starting at index, or + * null if no decoding is possible. + * + * Formats all are legal + * '' decodes to ' + */ + public Character decodeCharacter( PushbackSequence input ) { + input.mark(); + Character first = input.next(); + if ( first == null ) { + input.reset(); + return null; + } + + // if this is not an encoded character, return null + if ( first.charValue() != '\'' ) { + input.reset(); + return null; + } + + Character second = input.next(); + if ( second == null ) { + input.reset(); + return null; + } + + // if this is not an encoded character, return null + if ( second.charValue() != '\'' ) { + input.reset(); + return null; + } + return( Character.valueOf( '\'' ) ); + } + +} diff --git a/src/main/java/org/owasp/esapi/codecs/PercentCodec.java b/src/main/java/org/owasp/esapi/codecs/PercentCodec.java new file mode 100644 index 000000000..5775055bb --- /dev/null +++ b/src/main/java/org/owasp/esapi/codecs/PercentCodec.java @@ -0,0 +1,164 @@ +/** + * 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.codecs; + +import java.io.UnsupportedEncodingException; +import java.util.Set; + +import org.owasp.esapi.util.CollectionsUtil; + +/** + * Implementation of the Codec interface for percent encoding (aka URL encoding). + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @since June 1, 2007 + * @see org.owasp.esapi.Encoder + */ +public class PercentCodec extends AbstractCharacterCodec +{ + private static final String ALPHA_NUMERIC_STR = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + @SuppressWarnings("unused") + private static final String RFC3986_RESERVED_STR = ":/?#[]@!$&'()*+,;="; + private static final String RFC3986_NON_ALPHANUMERIC_UNRESERVED_STR = "-._~"; + // rfc3986 2.3: For consistency, percent-encoded octets + // in the ranges of ALPHA (%41-%5A and %61-%7A), DIGIT + // (%30-%39), hyphen (%2D), period (%2E), underscore + // (%5F), or tilde (%7E) should not be created by URI + // producers + private static final boolean ENCODED_NON_ALPHA_NUMERIC_UNRESERVED = true; + private static final String UNENCODED_STR = ALPHA_NUMERIC_STR + + (ENCODED_NON_ALPHA_NUMERIC_UNRESERVED ? "" : RFC3986_NON_ALPHANUMERIC_UNRESERVED_STR); + private static final Set UNENCODED_SET = CollectionsUtil.strToUnmodifiableSet(UNENCODED_STR); + + /** + * Convinence method to encode a string into UTF-8. This + * wraps the {@link UnsupportedEncodingException} that + * {@link String#getBytes(String)} throws in a + * {@link IllegalStateException} as UTF-8 support is required + * by the Java spec and should never throw this exception. + * @param str the string to encode + * @return str encoded in UTF-8 as bytes. + * @throws IllegalStateException wrapped {@link + * UnsupportedEncodingException} if + * {@link String.getBytes(String)} throws it. + */ + private static byte[] toUtf8Bytes(String str) + { + try + { + return str.getBytes("UTF-8"); + } + catch(UnsupportedEncodingException e) + { + throw new IllegalStateException("The Java spec requires UTF-8 support.", e); + } + } + + /** + * Append the two upper case hex characters for a byte. + * @param sb The string buffer to append to. + * @param b The byte to hexify + * @return sb with the hex characters appended. + */ + // rfc3986 2.1: For consistency, URI producers + // should use uppercase hexadecimal digits for all percent- + // encodings. + private static StringBuilder appendTwoUpperHex(StringBuilder sb, int b) + { + if(b < Byte.MIN_VALUE || b > Byte.MAX_VALUE) + throw new IllegalArgumentException("b is not a byte (was " + b + ')'); + b &= 0xFF; + if(b<0x10) + sb.append('0'); + return sb.append(Integer.toHexString(b).toUpperCase()); + } + + /** + * Encode a character for URLs + * @param immune Additional characters not to encode. Note this could + * break URL encoding as referenced in RFC 3986. You should + * especially be wary of including '%' in this list of immune + * characters since it is used as the "escape" character for + * the hex encoding and including it may result in subsequent + * and/or dangerous results when decoding. + * @param c character to encode + * @return the encoded string representing c + */ + public String encodeCharacter( char[] immune, Character c ) + { + String cStr = String.valueOf(c.charValue()); + byte[] bytes; + StringBuilder sb; + + // check for user specified immune characters + if ( immune != null && containsCharacter( c.charValue(), immune ) ) + return cStr; + + // check for standard characters (e.g., alphanumeric, etc.) + if(UNENCODED_SET.contains(c)) + return cStr; + + bytes = toUtf8Bytes(cStr); + sb = new StringBuilder(bytes.length * 3); + for(byte b : bytes) + appendTwoUpperHex(sb.append('%'), b); + return sb.toString(); + } + + /** + * {@inheritDoc} + * + * Formats all are legal both upper/lower case: + * %hh; + * + * @param input + * encoded character using percent characters (such as URL encoding) + */ + public Character decodeCharacter( PushbackSequence input ) { + input.mark(); + Character first = input.next(); + if ( first == null ) { + input.reset(); + return null; + } + + // if this is not an encoded character, return null + if (first != '%' ) { + input.reset(); + return null; + } + + // Search for exactly 2 hex digits following + StringBuilder sb = new StringBuilder(); + for ( int i=0; i<2; i++ ) { + Character c = input.nextHex(); + if ( c != null ) sb.append( c ); + } + if ( sb.length() == 2 ) { + try { + // parse the hex digit and create a character + int i = Integer.parseInt(sb.toString(), 16); + if (Character.isValidCodePoint(i)) { + return (char) i; + } + } catch( NumberFormatException ignored ) { } + } + input.reset(); + return null; + } + +} diff --git a/src/main/java/org/owasp/esapi/codecs/PushBackSequenceImpl.java b/src/main/java/org/owasp/esapi/codecs/PushBackSequenceImpl.java new file mode 100644 index 000000000..4f0847f1e --- /dev/null +++ b/src/main/java/org/owasp/esapi/codecs/PushBackSequenceImpl.java @@ -0,0 +1,136 @@ +package org.owasp.esapi.codecs; + + +/** + * 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. + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @since June 1, 2007 + * @see org.owasp.esapi.Encoder + */ +public class PushBackSequenceImpl extends AbstractPushbackSequence{ + /** + * + * @param input + */ + public PushBackSequenceImpl( String input ) { + super(input); + } + + /** + * + * @return The next value in this Sequence, as an Integer. + */ + public Integer next() { + if ( pushback != null ) { + Integer save = pushback; + pushback = null; + return save; + } + if ( input == null ) return null; + if ( input.length() == 0 ) return null; + if ( index >= input.length() ) return null; + final Integer point = input.codePointAt(index); + index += Character.charCount(point); + return point; + } + + /** + * + * @return The next value in this Sequence, as an Integer if it is a hex digit. Null otherwise. + */ + public Integer nextHex() { + Integer c = next(); + if ( c == null ) return null; + if ( isHexDigit( c ) ) return c; + return null; + } + + /** + * + * @return The next value in this Sequence, as an Integer if it is an octal digit. Null otherwise. + */ + public Integer nextOctal() { + Integer c = next(); + if ( c == null ) return null; + if ( isOctalDigit( c ) ) return c; + return null; + } + + /** + * Returns true if the parameter character is a hexadecimal digit 0 through 9, a through f, or A through F. + * @param c + * @return true if it is a hexadecimal digit, false otherwise. + */ + public static boolean isHexDigit( Integer c ) { + if ( c == null ) return false; + Integer ch = Integer.valueOf(c); + return (ch >= '0' && ch <= '9' ) || (ch >= 'a' && ch <= 'f' ) || (ch >= 'A' && ch <= 'F' ); + } + + /** + * Returns true if the parameter character is an octal digit 0 through 7. + * @param c + * @return true if it is an octal digit, false otherwise. + */ + public static boolean isOctalDigit( Integer c ) { + if ( c == null ) return false; + Integer ch = Integer.valueOf(c); + return ch >= '0' && ch <= '7'; + } + + /** + * Return the next codePoint without affecting the current index. + * @return the next codePoint + */ + public Integer peek() { + if ( pushback != null ) return pushback; + if ( input == null ) return null; + if ( input.length() == 0 ) return null; + if ( index >= input.length() ) return null; + return input.codePointAt(index); + } + + /** + * Test to see if the next codePoint is a particular value without affecting the current index. + * @param c + * @return if the next value is equal to the supplied value. + */ + public boolean peek( Integer c ) { + if ( pushback != null && pushback.intValue() == c ) return true; + if ( input == null ) return false; + if ( input.length() == 0 ) return false; + if ( index >= input.length() ) return false; + return input.codePointAt(index) == c; + } + + /** + * {@inheritDoc} + */ + public void mark() { + temp = pushback; + mark = index; + } + + /** + * {@inheritDoc} + */ + public void reset() { + pushback = temp; + index = mark; + } + + /** + * {@inheritDoc} + */ + public String remainder() { + String output = input.substring( index ); + if ( pushback != null ) { + output = pushback + output; + } + return output; + } + +} diff --git a/src/main/java/org/owasp/esapi/codecs/PushbackSequence.java b/src/main/java/org/owasp/esapi/codecs/PushbackSequence.java new file mode 100644 index 000000000..d2edcb652 --- /dev/null +++ b/src/main/java/org/owasp/esapi/codecs/PushbackSequence.java @@ -0,0 +1,89 @@ +/** + * 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) 2017 - 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 Matt Seil (mseil .at. owasp.org) + * @created 2017 + * + */ +package org.owasp.esapi.codecs; + +public interface PushbackSequence { + + /** + * + * @param c + */ + void pushback(T c); + + /** + * Get the current index of the PushbackString. Typically used in error messages. + * @return The current index of the PushbackSequence. + */ + int index(); + + /** + * Determine if this sequence has another element. + * + * @return True if there is another element in this sequence. False otherwise. + */ + boolean hasNext(); + + /** + * Return the next element in the Sequence and increment the current index. + * @return The next element in the Sequence. + */ + T next(); + + /** + * Return the next element in the Sequence in Hex format and increment the current index. + * @return The next element in the Sequence in Hex format (if that makes sense for this Sequence's type). + */ + T nextHex(); + + /** + * Return the next element in the Sequence in Octal format and increment the current index. + * @return The next element in the Sequence in Octal format (if that makes sense for this Sequence's type). + */ + T nextOctal(); + + /** + * Return the next element in the Sequence without affecting the current index. + * @return the next element in the Sequence. + */ + T peek(); + + /** + * Test to see if the next element in the Sequence matches the supplied value without affecting the current index. + * @param c The value to match against. + * @return True if the next element matches the supplied value. False otherwise. + */ + boolean peek(T c); + + /** + * Mark the location of the current index. + */ + void mark(); + + /** + * Set the index back to the last marked location. + */ + void reset(); + + /** + * Not at all sure what this method is intended to do. There + * is a line in HTMLEntityCodec that said calling this method + * is a "kludge around PushbackString..." + * @return Return the remaining portion of the sequence, with any pushback appended to the front (if any). + */ + String remainder(); + +} \ No newline at end of file diff --git a/src/main/java/org/owasp/esapi/codecs/PushbackString.java b/src/main/java/org/owasp/esapi/codecs/PushbackString.java new file mode 100644 index 000000000..377ed829e --- /dev/null +++ b/src/main/java/org/owasp/esapi/codecs/PushbackString.java @@ -0,0 +1,223 @@ +/** + * 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) 2017 - 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 Matt Seil (mseil .at. owasp.org) + * @updated 2017 + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @created 2007 + */ +package org.owasp.esapi.codecs; + +/** + * 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. + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) + * Aspect Security + * @since June 1, 2007 + * @see org.owasp.esapi.Encoder + */ +public class PushbackString extends AbstractPushbackSequence { + + /** + * @param input Construct a PushbackString with the specified String. + */ + public PushbackString(String input) { + super(input); + } + + /* + * (non-Javadoc) + * + * @see org.owasp.esapi.codecs.PushbackSequence#index() + */ + public int index() { + return index; + } + + /* + * (non-Javadoc) + * + * @see org.owasp.esapi.codecs.PushbackSequence#hasNext() + */ + public boolean hasNext() { + if (pushback != null){ + return true; + } + if (input == null){ + return false; + } + if (input.length() == 0){ + return false; + } + if (index >= input.length()){ + return false; + } + return true; + } + + /* + * (non-Javadoc) + * + * @see org.owasp.esapi.codecs.PushbackSequence#next() + */ + public Character next() { + if (pushback != null) { + Character save = pushback; + pushback = null; + return save; + } + if (input == null){ + return null; + } + if (input.length() == 0){ + return null; + } + if (index >= input.length()){ + return null; + } + return Character.valueOf(input.charAt(index++)); + } + + /* + * (non-Javadoc) + * + * @see org.owasp.esapi.codecs.PushbackSequence#nextHex() + */ + public Character nextHex() { + Character c = next(); + if (c == null){ + return null; + } + if (isHexDigit(c)){ + return c; + } + return null; + } + + /* + * (non-Javadoc) + * + * @see org.owasp.esapi.codecs.PushbackSequence#nextOctal() + */ + public Character nextOctal() { + Character c = next(); + if (c == null){ + return null; + } + if (isOctalDigit(c)){ + return c; + } + return null; + } + + /** + * Returns true if the parameter character is a hexadecimal digit 0 through + * 9, a through f, or A through F. + * + * @param c + * @return true if it is a hexadecimal digit, false otherwise. + */ + public static boolean isHexDigit(Character c) { + if (c == null){ + return false; + } + char ch = c.charValue(); + return (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F'); + } + + /** + * Returns true if the parameter character is an octal digit 0 through 7. + * + * @param c + * @return true if it is an octal digit, false otherwise. + */ + public static boolean isOctalDigit(Character c) { + if (c == null){ + return false; + } + char ch = c.charValue(); + return ch >= '0' && ch <= '7'; + } + + /* + * (non-Javadoc) + * + * @see org.owasp.esapi.codecs.PushbackSequence#peek() + */ + public Character peek() { + if (pushback != null){ + return pushback; + } + if (input == null){ + return null; + } + if (input.length() == 0){ + return null; + } + if (index >= input.length()){ + return null; + } + return Character.valueOf(input.charAt(index)); + } + + /* + * (non-Javadoc) + * + * @see org.owasp.esapi.codecs.PushbackSequence#peek(char) + */ + public boolean peek(Character c) { + if (pushback != null && pushback.charValue() == c){ + return true; + } + if (input == null){ + return false; + } + if (input.length() == 0){ + return false; + } + if (index >= input.length()){ + return false; + } + return input.charAt(index) == c; + } + + /** + * {@inheritDoc} + */ + public void mark() { + temp = pushback; + mark = index; + } + + /** + * {@inheritDoc} + */ + public void reset() { + pushback = temp; + index = mark; + } + + /** + * {@inheritDoc} + */ + public String remainder() { + String output = input.substring(index); + if (pushback != null) { + output = pushback + output; + } + return output; + } +} \ No newline at end of file diff --git a/src/main/java/org/owasp/esapi/codecs/Trie.java b/src/main/java/org/owasp/esapi/codecs/Trie.java new file mode 100644 index 000000000..fbb8c99ec --- /dev/null +++ b/src/main/java/org/owasp/esapi/codecs/Trie.java @@ -0,0 +1,172 @@ +package org.owasp.esapi.codecs; + +import java.io.IOException; +import java.io.PushbackReader; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.Set; + +public interface Trie extends Map +{ + public Map.Entry getLongestMatch(CharSequence key); + public Map.Entry getLongestMatch(PushbackReader keyIn) throws IOException; + public int getMaxKeyLength(); + + static class TrieProxy implements Trie + { + private Trie wrapped; + + TrieProxy(Trie toWrap) + { + wrapped = toWrap; + } + + protected Trie getWrapped() + { + return wrapped; + } + + public Map.Entry getLongestMatch(CharSequence key) + { + return wrapped.getLongestMatch(key); + } + + public Map.Entry getLongestMatch(PushbackReader keyIn) throws IOException + { + return wrapped.getLongestMatch(keyIn); + } + + public int getMaxKeyLength() + { + return wrapped.getMaxKeyLength(); + } + + /* java.util.Map: */ + + public int size() + { + return wrapped.size(); + } + + public boolean isEmpty() + { + return wrapped.isEmpty(); + } + + public boolean containsKey(Object key) + { + return wrapped.containsKey(key); + } + + public boolean containsValue(Object val) + { + return wrapped.containsValue(val); + } + + public T get(Object key) + { + return wrapped.get(key); + } + + public T put(CharSequence key, T value) + { + return wrapped.put(key, value); + } + + public T remove(Object key) + { + return wrapped.remove(key); + } + + public void putAll(Map t) + { + wrapped.putAll(t); + } + + public void clear() + { + wrapped.clear(); + } + + public Set keySet() + { + return wrapped.keySet(); + } + + public Collection values() + { + return wrapped.values(); + } + + public Set> entrySet() + { + return wrapped.entrySet(); + } + + public boolean equals(Object other) + { + return wrapped.equals(other); + } + + public int hashCode() + { + return wrapped.hashCode(); + } + } + + static class Unmodifiable extends TrieProxy + { + Unmodifiable(Trie toWrap) + { + super(toWrap); + } + + public T put(CharSequence key, T value) + { + throw new UnsupportedOperationException("Unmodifiable Trie"); + } + + public T remove(CharSequence key) + { + throw new UnsupportedOperationException("Unmodifiable Trie"); + } + + public void putAll(Map t) + { + throw new UnsupportedOperationException("Unmodifiable Trie"); + } + + public void clear() + { + throw new UnsupportedOperationException("Unmodifiable Trie"); + } + + public Set keySet() + { + return Collections.unmodifiableSet(super.keySet()); + } + + public Collection values() + { + return Collections.unmodifiableCollection(super.values()); + } + + public Set> entrySet() + { + return Collections.unmodifiableSet(super.entrySet()); + } + } + + public static class Util + { + private Util() + { + } + + static Trie unmodifiable(Trie toWrap) + { + return new Unmodifiable(toWrap); + } + } +} diff --git a/src/main/java/org/owasp/esapi/codecs/UnixCodec.java b/src/main/java/org/owasp/esapi/codecs/UnixCodec.java new file mode 100644 index 000000000..aa513b94e --- /dev/null +++ b/src/main/java/org/owasp/esapi/codecs/UnixCodec.java @@ -0,0 +1,86 @@ +/** + * 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.codecs; + + +/** + * Implementation of the {@code Codec} interface for '\' encoding from Unix command shell (bash lineage, not csh lineage). + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @since June 1, 2007 + * @see org.owasp.esapi.Encoder + */ +public class UnixCodec extends AbstractCharacterCodec { + + /** + * {@inheritDoc} + * + * @return the backslash-encoded character + * + * @param immune Array of characters that should not be encoded. Use with caution! All + * alphanumeric characters are "immune" by default so you needn't + * include them. + */ + public String encodeCharacter( char[] immune, Character c ) { + char ch = c.charValue(); + + // check for immune characters + if ( containsCharacter( ch, immune ) ) { + return ""+ch; + } + + // check for alphanumeric characters + String hex = super.getHexForNonAlphanumeric( ch ); + if ( hex == null ) { + return ""+ch; + } + + return "\\" + c; + } + + + /** + * {@inheritDoc} + * + *

+ * Formats all are legal both upper/lower case: + *

+     *   \x - all special characters
+     * 
+ * + * @return the decoded version of the character starting at index, or + * null if no decoding is possible. + */ + public Character decodeCharacter( PushbackSequence input ) { + input.mark(); + Character first = input.next(); + if ( first == null ) { + input.reset(); + return null; + } + + // if this is not an encoded character, return null + if ( first.charValue() != '\\' ) { + input.reset(); + return null; + } + + Character second = input.next(); + return second; + } + +} diff --git a/src/main/java/org/owasp/esapi/codecs/VBScriptCodec.java b/src/main/java/org/owasp/esapi/codecs/VBScriptCodec.java new file mode 100644 index 000000000..5f768ec4f --- /dev/null +++ b/src/main/java/org/owasp/esapi/codecs/VBScriptCodec.java @@ -0,0 +1,117 @@ +/** + * 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.codecs; + +import org.owasp.esapi.EncoderConstants; + + +/** + * Implementation of the Codec interface for 'quote' encoding from VBScript. + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @since June 1, 2007 + * @see org.owasp.esapi.Encoder + */ +public class VBScriptCodec extends AbstractCharacterCodec { + + /** + * Encode a String so that it can be safely used in a specific context. + * + * @param immune + * @param input + * the String to encode + * @return the encoded String + */ + public String encode(char[] immune, String input) { + StringBuilder sb = new StringBuilder(); + boolean encoding = false; + boolean inquotes = false; + for ( int i=0; i 0 ) sb.append( "&" ); + if ( !inquotes && i > 0 ) sb.append( "\"" ); + sb.append( c ); + inquotes = true; + encoding = false; + + // handle characters that need encoding + } else { + if ( inquotes && i < input.length() ) sb.append( "\"" ); + if ( i > 0 ) sb.append( "&" ); + sb.append( encodeCharacter( immune, Character.valueOf( c ) ) ); + inquotes = false; + encoding = true; + } + } + return sb.toString(); + } + + + /** + * Returns quote-encoded character + * + * @param immune + */ + public String encodeCharacter( char[] immune, Character c ) { + char ch = c.charValue(); + + // check for immune characters + if ( containsCharacter( ch, immune ) ) { + return ""+ch; + } + + // check for alphanumeric characters + String hex = super.getHexForNonAlphanumeric( ch ); + if ( hex == null ) { + return ""+ch; + } + + return "chrw(" + (int)c.charValue() + ")"; + } + + + + /** + * 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 + */ + public Character decodeCharacter( PushbackSequence input ) { + input.mark(); + Character first = input.next(); + if ( first == null ) { + input.reset(); + return null; + } + + // if this is not an encoded character, return null + if ( first.charValue() != '\"' ) { + input.reset(); + return null; + } + + Character second = input.next(); + return second; + } + +} \ No newline at end of file diff --git a/src/main/java/org/owasp/esapi/codecs/WindowsCodec.java b/src/main/java/org/owasp/esapi/codecs/WindowsCodec.java new file mode 100644 index 000000000..d3338b1be --- /dev/null +++ b/src/main/java/org/owasp/esapi/codecs/WindowsCodec.java @@ -0,0 +1,82 @@ +/** + * 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.codecs; + + +/** + * Implementation of the Codec interface for '^' encoding from Windows command shell. + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @since June 1, 2007 + * @see org.owasp.esapi.Encoder + */ +public class WindowsCodec extends AbstractCharacterCodec { + + + /** + * {@inheritDoc} + * + * Returns Windows shell encoded character (which is ^) + * + * @param immune + */ + public String encodeCharacter( char[] immune, Character c ) { + char ch = c.charValue(); + + // check for immune characters + if ( containsCharacter( ch, immune ) ) { + return ""+ch; + } + + // check for alphanumeric characters + String hex = super.getHexForNonAlphanumeric( ch ); + if ( hex == null ) { + return ""+ch; + } + + return "^" + c; + } + + + /** + * {@inheritDoc} + * + * 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 + */ + public Character decodeCharacter( PushbackSequence input ) { + input.mark(); + Character first = input.next(); + if ( first == null ) { + input.reset(); + return null; + } + + // if this is not an encoded character, return null + if ( first.charValue() != '^' ) { + input.reset(); + return null; + } + + Character second = input.next(); + return second; + } + +} \ No newline at end of file diff --git a/src/main/java/org/owasp/esapi/codecs/XMLEntityCodec.java b/src/main/java/org/owasp/esapi/codecs/XMLEntityCodec.java new file mode 100644 index 000000000..c28734387 --- /dev/null +++ b/src/main/java/org/owasp/esapi/codecs/XMLEntityCodec.java @@ -0,0 +1,298 @@ +/** + * 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) 2009 - 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.codecs; + +import java.util.Map; +import java.util.Set; + +import org.owasp.esapi.util.CollectionsUtil; + +/** + * Implementation of the Codec interface for XML entity encoding. + * This differes from HTML entity encoding in that only the following + * named entities are predefined: + *

    + *
  • lt
  • + *
  • gt
  • + *
  • amp
  • + *
  • apos
  • + *
  • quot
  • + *
+ * However, the XML Specification 1.0 states in section 4.6 "Predefined + * Entities" that these should still be declared for interoperability + * purposes. As such, encoding in this class will not use them. + * + * It's also worth noting that unlike the HTMLEntityCodec, a trailing + * semicolon is required and all valid codepoints are accepted. + * + * Note that it is a REALLY bad idea to use this for decoding as an XML + * document can declare arbitrary entities that this Codec has no way + * of knowing about. Decoding is included for completeness but it's use + * is not recommended. Use a XML parser instead! + */ +public class XMLEntityCodec extends AbstractCharacterCodec +{ + private static final String ALPHA_NUMERIC_STR = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + private static final String UNENCODED_STR = ALPHA_NUMERIC_STR + " \t"; + private static final Set UNENCODED_SET = CollectionsUtil.strToUnmodifiableSet(UNENCODED_STR); + private static final HashTrie entityToCharacterMap; + + static + { // populate entitites + entityToCharacterMap = new HashTrie(); + entityToCharacterMap.put("lt", '<'); + entityToCharacterMap.put("gt", '>'); + entityToCharacterMap.put("amp", '&'); + entityToCharacterMap.put("apos", '\''); + entityToCharacterMap.put("quot", '"'); + } + + /** + * {@inheritDoc} + * + * Encodes a Character using XML entities as necessary. + * + * @param immune characters that should not be encoded as entities + */ + public String encodeCharacter(char[] immune, Character c) + { + // check for immune characters + if(containsCharacter(c, immune)) + return c.toString(); + + // check for unencoded characters + if(UNENCODED_SET.contains(c)) + return c.toString(); + + return "&#x" + Integer.toHexString(c.charValue()) + ";"; + } + + /** + * {@inheritDoc} + * + * Returns the decoded version of the character starting at index, or + * null if no decoding is possible. + * + * Legal formats: + *
    + *
  • &#dddd;
  • + *
  • &#xhhhh;
  • + *
  • &name;
  • + *
+ */ + public Character decodeCharacter(PushbackSequence input) + { + Character ret = null; + Character first; + Character second; + + input.mark(); + try + { + first = input.next(); + if(first == null) + return null; + + // if this is not an encoded character, return null + if(first != '&') + return null; + + // test for numeric encodings + second = input.next(); + if(second==null) + return null; + + if(second=='#') + { // handle numbers + ret = getNumericEntity(input); + } + else if(Character.isLetter(second.charValue())) + { // handle entities + input.pushback(second); + ret = getNamedEntity(input); + } + } + finally + { + if(ret == null) + input.reset(); + } + return ret; + } + + /** + * Converts the rest of a numeric entity to a character. + * @param input The input to read from. It is assumed that input + * is positioned at the character after the &# + * @return The character decoded or null on failure. + */ + private static Character getNumericEntity(PushbackSequence input) + { + Character first = input.peek(); + + if(first == null) + return null; + + if(first=='x'||first=='X') + { + input.next(); // nuke X + return parseHex(input); + } + return parseNumber(input); + } + + /** + * Convert a integer code point to a Character. + * @param i the integer + * @return i as a Character or null if i is a invalid code point + * or outside of the Java char range. + */ + private static Character int2char(int i) + { + if(!Character.isValidCodePoint(i)) + return null; + if(!(Character.MIN_VALUE <= i && i <= Character.MAX_VALUE)) + return null; // we can't 0x010000-0x100000 currently + return (char)i; + } + + /** + * Converts the rest of a decimal numeric entity to a character. + * @param input The input to read from. It is assumed that input + * is positioned at the character after the &# and that + * the next char is not a 'x' or 'X'. + * @return The character decoded or null on failutre. + */ + private static Character parseNumber(PushbackSequence input) + { + StringBuilder sb = new StringBuilder(); + Character c; + while((c=input.next())!=null) + { + // end of entity? + if(c==';') + break; + + // check for digit + if(!Character.isDigit(c.charValue())) + return null; + sb.append(c); + } + if(c==null) + return null; // not ';' termintated + if(sb.length()<=0) // no digits + return null; + try + { + return int2char(Integer.parseInt(sb.toString())); + } + catch(NumberFormatException e) + { + return null; + } + } + + /** + * Converts the rest of a hexidecimal numeric entity to a character. + * @param input The input to read from. It is assumed that input + * is positioned at the character after the &#[xX] + * @return The character decoded or null on failutre. + */ + private static Character parseHex(PushbackSequence input) + { + Character c; + StringBuilder sb = new StringBuilder(); + input_loop: while((c=input.next())!=null) + { + switch(c.charValue()) + { + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + sb.append(c); + break; + case ';': + break input_loop; + default: + return null; + } + } + if(c==null) + return null; // not ';' termintated + if(sb.length()<=0) // no digits + return null; + try + { + return int2char(Integer.parseInt(sb.toString(),16)); + } + catch(NumberFormatException e) + { + return null; + } + } + + /** + * + * Converts the rest of a named entity to a character. + * null if no decoding is possible. + * @param input The input to read from. It is assumed that input + * is positioned at the character after the &. + * @return The character decoded or null on failutre. + */ + private Character getNamedEntity(PushbackSequence input) + { + StringBuilder possible = new StringBuilder(); + Map.Entry entry; + int len; + + // kludge around PushbackString.... + len = Math.min(input.remainder().length(), entityToCharacterMap.getMaxKeyLength()+1); + for(int i=0;i + + + + + + +This package contains codecs for application layer encoding/escaping schemes that can be used for +both canonicalization and output encoding. By using the codecs to decode (canonicalize) input +before validation, many attacks can be detected and handled. By using the codecs to encode +untrusted data before sending it to an interpreter, a wide variety of 'injection' attacks can +be stopped. However, +this package does not currently address issues related to converting between byte-streams and +internal character representations, such as overlong UTF-8 issues. Those are left to the platform. +The codecs cover protocol encodings such as HTML entity encoding and percent encoding, but also +common product escaping schemes, such as Unix, Windows, MySQL, and Oracle. + + + diff --git a/src/main/java/org/owasp/esapi/codecs/ref/EncodingPatternPreservation.java b/src/main/java/org/owasp/esapi/codecs/ref/EncodingPatternPreservation.java new file mode 100644 index 000000000..9ca5c51a8 --- /dev/null +++ b/src/main/java/org/owasp/esapi/codecs/ref/EncodingPatternPreservation.java @@ -0,0 +1,111 @@ +package org.owasp.esapi.codecs.ref; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * String mutation utility which can be used to replace all occurrences of a + * defined regular expression with a marker string, and also restore the + * original string content. + * + */ +public class EncodingPatternPreservation { + /** Default replacement marker. */ + private static final String REPLACEMENT_MARKER = EncodingPatternPreservation.class.getSimpleName(); + /** Pattern that is used to identify which content should be replaced. */ + private final Pattern noEncodeContent; + /** The Marker used to replace found Pattern references. */ + private String replacementMarker = REPLACEMENT_MARKER; + + /** + * The ordered-list of elements that were replaced in the last call to + * {@link #captureAndReplaceMatches(String)}, and that will be used to replace + * the {@link #replacementMarker} on the next call to + * {@link #restoreOriginalContent(String)} + */ + private final List replacedContentList = new ArrayList<>(); + + /** + * Constructor. + * + * @param pattern Pattern identifying content being replaced. + */ + public EncodingPatternPreservation(Pattern pattern) { + noEncodeContent = pattern; + } + + /** + * Replaces each matching instance of this instance's Pattern with an + * identifiable replacement marker.
+ * + *
+ * After the encoding process is complete, use + * {@link #restoreOriginalContent(String)} to re-insert the original data. + * + * @param input String to adjust + * @return The adjusted String + */ + public String captureAndReplaceMatches(String input) { + if (!replacedContentList.isEmpty()) { + // This may seem odd, but this will prevent programmer error that would result + // in being unable to restore a previously tokenized String. + String message = "Previously captured state is still present in instance. Call PatternContentPreservation.reset() to clear out preserved state and to reuse the reference."; + throw new IllegalStateException(message); + } + String inputCpy = input; + Matcher matcher = noEncodeContent.matcher(input); + + while (matcher.find()) { + String replaceContent = matcher.group(0); + if (replaceContent != null) { + replacedContentList.add(replaceContent); + inputCpy = inputCpy.replaceFirst(noEncodeContent.pattern(), replacementMarker); + } + } + + return inputCpy; + } + + /** + * Replaces each instance of the {@link #replacementMarker} with the original + * content, as captured by {@link #captureAndReplaceMatches(String)} + * + * @param input String to restore. + * @return String reference with all values replaced. + */ + public String restoreOriginalContent(String input) { + String result = input; + while (replacedContentList.size() > 0) { + String origValue = replacedContentList.remove(0); + result = result.replaceFirst(replacementMarker, origValue); + } + + return result; + + } + + /** + * Allows the marker used as a replacement to be altered. + * + * @param marker String replacement to use for regex matches. + */ + public void setReplacementMarker(String marker) { + if (!replacedContentList.isEmpty()) { + // This may seem odd, but this will prevent programmer error that would result + // in being unable to restore a previously tokenized String. + String message = "Previously captured state is still present in instance. Call PatternContentPreservation.reset() to clear out preserved state and to alter the marker."; + throw new IllegalStateException(message); + } + this.replacementMarker = marker; + } + + /** + * Clears any stored replacement values out of the instance. + */ + public void reset() { + replacedContentList.clear(); + } + +} diff --git a/src/main/java/org/owasp/esapi/configuration/AbstractPrioritizedPropertyLoader.java b/src/main/java/org/owasp/esapi/configuration/AbstractPrioritizedPropertyLoader.java new file mode 100644 index 000000000..2ca897707 --- /dev/null +++ b/src/main/java/org/owasp/esapi/configuration/AbstractPrioritizedPropertyLoader.java @@ -0,0 +1,117 @@ +package org.owasp.esapi.configuration; + + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Properties; + +/** + * Abstract class that supports two "levels" of priorities for ESAPI properties. + * The higher level is the property file supported by an "operations" team and + * the lower level is the property file intended to be supported by the + * "development" team. ESAPI properties defined in the lower level properties + * file cannot supersede properties defined in the higher level properties file. + * + * The intent os to place ESAPI properties related to enterprise-wide security + * policy (e.g., the minimum sized encryption key, + * Encryptor.MinEncryptionKeyLength in the higher level so the + * development team cannot dumb down the policy, either accidentally or + * intentionally. (This of course requires that the developers don't provide the + * operations team the properties file for them to use. :) This is also good for + * allowing the productions operations team to select property values for + * properties such as Encryptor.MasterKey and Encryptor.MasterSalt + * so that they are only on a "need-to-know" basis and don't accidentally get + * committed to the development team's SCM repository. + * + * @since 2.2 + */ +public abstract class AbstractPrioritizedPropertyLoader implements EsapiPropertyLoader, + Comparable { + + protected final String filename; + protected Properties properties; + + private final int priority; + + public AbstractPrioritizedPropertyLoader(String filename, int priority) throws IOException { + this.priority = priority; + this.filename = filename; + initProperties(); + } + + /** + * Get priority of this property loader. If two and more loaders can return value for the same property key, + * the one with the highest priority will be chosen. + * @return priority of this property loader + */ + public int priority() { + return priority; + } + + @Override + public int compareTo(AbstractPrioritizedPropertyLoader compared) { + if (this.priority > compared.priority()) { + return 1; + } else if (this.priority < compared.priority()) { + return -1; + } + return 0; + } + + public String name() { + return filename; + } + + /** + * Initializes properties object and fills it with data from configuration file. + */ + private void initProperties() throws IOException { + properties = new Properties(); + File file = new File(filename); + if (file.exists() && file.isFile()) { + if ( file.canRead() ) { + loadPropertiesFromFile(file); + } else { + throw new IOException("Can't read specificied configuration file: " + filename); + } + } else { + throw new FileNotFoundException("Specified configuration file " + filename + " does not exist or not regular file"); + } + } + + /** + * Method that loads the data from configuration file to properties object. + * @param file + */ + protected abstract void loadPropertiesFromFile(File file); + + /** + * Used to log errors to the console during the loading of the properties file itself. Can't use + * standard logging in this case, since the Logger may not be initialized yet. Output is sent to + * {@code PrintStream} {@code System.out}. Output is discarded if the {@code System} property + * "org.owasp.esapi.logSpecial.discard" is set to {@code true}. + * + * @param msg The message to log to the console. + * @param t Associated exception that was caught. + */ + protected final void logSpecial(String msg, Throwable t) { + // Note: It is really distasteful to tie this class to DefaultSecurityConfiguration + // like this, but the alternative is to move the logSpecial() and + // logToStdout() some utilities class and that is even more + // distasteful because it may encourage people to use these. -kwwall + org.owasp.esapi.reference.DefaultSecurityConfiguration.logToStdout(msg, t); + } + + /** + * Used to log errors to the console during the loading of the properties file itself. Can't use + * standard logging in this case, since the Logger may not be initialized yet. Output is sent to + * {@code PrintStream} {@code System.out}. Output is discarded if the {@code System} property + * "org.owasp.esapi.logSpecial.discard" is set to {@code true}. + * + * @param msg The message to log to the console. + */ + protected final void logSpecial(String msg) { + logSpecial(msg, null); + } +} diff --git a/src/main/java/org/owasp/esapi/configuration/EsapiPropertyLoader.java b/src/main/java/org/owasp/esapi/configuration/EsapiPropertyLoader.java new file mode 100644 index 000000000..7709483bf --- /dev/null +++ b/src/main/java/org/owasp/esapi/configuration/EsapiPropertyLoader.java @@ -0,0 +1,45 @@ +package org.owasp.esapi.configuration; + +import org.owasp.esapi.errors.ConfigurationException; + +/** + * Generic interface for loading security configuration properties. + * + * @since 2.2 + */ +public interface EsapiPropertyLoader { + + /** + * Get any int type property from security configuration. + * + * @return property value. + * @throws ConfigurationException when property does not exist in configuration or has incorrect type. + */ + public int getIntProp(String propertyName) throws ConfigurationException; + + /** + * Get any byte array type property from security configuration. + * + * @return property value. + * @throws ConfigurationException when property does not exist in configuration or has incorrect type. + */ + public byte[] getByteArrayProp(String propertyName) throws ConfigurationException; + + /** + * Get any Boolean type property from security configuration. + * + * @return property value. + * @throws ConfigurationException when property does not exist in configuration or has incorrect type. + */ + public Boolean getBooleanProp(String propertyName) throws ConfigurationException; + + /** + * Get any property from security configuration. As every property can be returned as string, this method + * throws exception only when property does not exist. + * + * @return property value. + * @throws ConfigurationException when property does not exist in configuration. + */ + public String getStringProp(String propertyName) throws ConfigurationException; + +} diff --git a/src/main/java/org/owasp/esapi/configuration/EsapiPropertyLoaderFactory.java b/src/main/java/org/owasp/esapi/configuration/EsapiPropertyLoaderFactory.java new file mode 100644 index 000000000..d6a1dffcd --- /dev/null +++ b/src/main/java/org/owasp/esapi/configuration/EsapiPropertyLoaderFactory.java @@ -0,0 +1,59 @@ +package org.owasp.esapi.configuration; + +import org.owasp.esapi.configuration.consts.EsapiConfiguration; +import org.owasp.esapi.errors.ConfigurationException; + +import java.io.IOException; + +import static org.owasp.esapi.configuration.consts.EsapiConfigurationType.PROPERTIES; +import static org.owasp.esapi.configuration.consts.EsapiConfigurationType.XML; + +/** + * Factory class that takes care of initialization of proper instance of EsapiPropertyLoader + * based on EsapiPropertiesStore + * + * @since 2.2 + */ +public class EsapiPropertyLoaderFactory { + + public static AbstractPrioritizedPropertyLoader createPropertyLoader(EsapiConfiguration cfg) + throws ConfigurationException, IOException { + String cfgPath = System.getProperty(cfg.getConfigName()); + if ( cfgPath == null || cfgPath.equals("") ) { + // TODO / FIXME: + // This case was previously a warning, but it should NOT have been + // since these system properties are optional. Most people just use + // the traditional ESAPI.properties file and not these prioritized ones. + // A warning gets logged in EsapiPropertyManager if logSpecial output + // has not been discarded. + // + // Note also there were a LOT of cases in our JUnit tests where the + // file extension was empty, causing the ConfigurationException to + // be thrown with the error message: + // "Configuration storage type [] is not supported" + // I don't think that was intentional, but because prior to the + // changes for this commit, these were all ConfigurationExceptions + // and they all were just being caught and not re-thrown by + // DefaultSecurityConfigurator. I think that is an error, probably + // in the tests, but I don't have timed to chase it down right now + // because of the pending 2.2.0.0 release. + // + // Also, I made several fixes in DefaultSecurityConfiguration + // related to this clean-up where IOExceptions were being silently + // caught when they should not have been. -kwwall + return null; + } + String fileExtension = cfgPath.substring(cfgPath.lastIndexOf('.') + 1); + + if (XML.getTypeName().equalsIgnoreCase(fileExtension)) { + return new XmlEsapiPropertyLoader(cfgPath, cfg.getPriority()); + } + if (PROPERTIES.getTypeName().equalsIgnoreCase(fileExtension)) { + return new StandardEsapiPropertyLoader(cfgPath, cfg.getPriority()); + } else { + throw new ConfigurationException("The extension of given configuration path [ " + cfgPath + " ] is not supported." + + "Only .xml or .properties file extensions are supported."); + } + } + +} diff --git a/src/main/java/org/owasp/esapi/configuration/EsapiPropertyManager.java b/src/main/java/org/owasp/esapi/configuration/EsapiPropertyManager.java new file mode 100644 index 000000000..94b5e4d5a --- /dev/null +++ b/src/main/java/org/owasp/esapi/configuration/EsapiPropertyManager.java @@ -0,0 +1,121 @@ +package org.owasp.esapi.configuration; + +import org.owasp.esapi.configuration.consts.EsapiConfiguration; +import org.owasp.esapi.errors.ConfigurationException; + +import java.util.TreeSet; +import java.io.IOException; + +import static org.owasp.esapi.configuration.EsapiPropertyLoaderFactory.createPropertyLoader; + +// Have dependency like this on a reference implmentation is majorly ugly, I know, but I +// don't want to refactor code and delay the 2.2.0.0 release further and this class +// is WAY too noisy. - kwwall +import static org.owasp.esapi.reference.DefaultSecurityConfiguration.logToStdout; + +/** + * Manager used for loading security configuration properties. Does all the logic to obtain the correct property from + * correct source. Uses following system properties to find configuration files: + *
+ * - org.owasp.esapi.devteam - lower priority dev file path
+ * - org.owasp.esapi.opsteam - higher priority ops file path
+ * 
+ * + * @since 2.2 + */ +public class EsapiPropertyManager implements EsapiPropertyLoader { + + protected TreeSet loaders; + + public EsapiPropertyManager() throws IOException { + initLoaders(); + } + + /** + * {@inheritDoc} + */ + @Override + public int getIntProp(String propertyName) throws ConfigurationException { + for (AbstractPrioritizedPropertyLoader loader : loaders) { + try { + return loader.getIntProp(propertyName); + } catch (ConfigurationException e) { + logToStdout("Integer property '" + propertyName + "' not found in " + loader.name(), e); + } + } + throw new ConfigurationException("Could not find property " + propertyName + " in configuration"); + } + + /** + * {@inheritDoc} + */ + @Override + public byte[] getByteArrayProp(String propertyName) throws ConfigurationException { + for (AbstractPrioritizedPropertyLoader loader : loaders) { + try { + return loader.getByteArrayProp(propertyName); + } catch (ConfigurationException e) { + logToStdout("Byte array property '" + propertyName + "' not found in " + loader.name(), e); + } + } + throw new ConfigurationException("Could not find property " + propertyName + " in configuration"); + } + + /** + * {@inheritDoc} + */ + @Override + public Boolean getBooleanProp(String propertyName) throws ConfigurationException { + for (AbstractPrioritizedPropertyLoader loader : loaders) { + try { + return loader.getBooleanProp(propertyName); + } catch (ConfigurationException e) { + logToStdout("Boolean property '" + propertyName + "' not found in " + loader.name(), e); + } + } + throw new ConfigurationException("Could not find property " + propertyName + " in configuration"); + } + + /** + * {@inheritDoc} + */ + @Override + public String getStringProp(String propertyName) throws ConfigurationException { + for (AbstractPrioritizedPropertyLoader loader : loaders) { + try { + return loader.getStringProp(propertyName); + } catch (ConfigurationException e) { + logToStdout("Property '" + propertyName + "' not found in " + loader.name(), e); + } + } + throw new ConfigurationException("Could not find property " + propertyName + " in configuration"); + } + + private void initLoaders() throws IOException { + loaders = new TreeSet(); + try { + AbstractPrioritizedPropertyLoader appl = createPropertyLoader(EsapiConfiguration.OPSTEAM_ESAPI_CFG); + if ( appl == null ) { + String msg = "WARNING: System property [" + EsapiConfiguration.OPSTEAM_ESAPI_CFG.getConfigName() + "] is not set"; + logToStdout(msg, null); + } else { + loaders.add( appl ); + } + } catch (IOException e) { + logToStdout("WARNING: Exception encountered while setting up ESAPI configuration manager for OPS team", e); + throw e; + } + try { + AbstractPrioritizedPropertyLoader appl = createPropertyLoader(EsapiConfiguration.DEVTEAM_ESAPI_CFG); + if ( appl == null ) { + String msg = "WARNING: System property [" + EsapiConfiguration.DEVTEAM_ESAPI_CFG.getConfigName() + "] is not set"; + logToStdout(msg, null); + } else { + loaders.add( appl ); + } + } catch (IOException e) { + logToStdout("WARNING: Exception encountered while setting up ESAPI configuration manager for DEV team", e); + throw e; + } + } +} diff --git a/src/main/java/org/owasp/esapi/configuration/StandardEsapiPropertyLoader.java b/src/main/java/org/owasp/esapi/configuration/StandardEsapiPropertyLoader.java new file mode 100644 index 000000000..fe50e02d7 --- /dev/null +++ b/src/main/java/org/owasp/esapi/configuration/StandardEsapiPropertyLoader.java @@ -0,0 +1,107 @@ +package org.owasp.esapi.configuration; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.errors.ConfigurationException; + +import java.io.*; + +/** + * Loader capable of loading single security configuration property from standard java properties configuration file. + * + * @since 2.2 + */ +public class StandardEsapiPropertyLoader extends AbstractPrioritizedPropertyLoader { + + public StandardEsapiPropertyLoader(String filename, int priority) throws IOException { + super(filename, priority); + } + + /** + * {@inheritDoc} + */ + @Override + public int getIntProp(String propertyName) throws ConfigurationException { + String property = properties.getProperty(propertyName); + if (property == null) { + throw new ConfigurationException("Property : " + propertyName + "not found in configuration"); + } + try { + return Integer.parseInt(property); + } catch (NumberFormatException e) { + throw new ConfigurationException("Incorrect type of : " + propertyName + ". Value " + property + + "cannot be converted to integer", e); + } + } + + /** + * {@inheritDoc} + */ + @Override + public byte[] getByteArrayProp(String propertyName) throws ConfigurationException { + String property = properties.getProperty(propertyName); + if (property == null) { + throw new ConfigurationException("Property : " + propertyName + "not found in default configuration"); + } + try { + return ESAPI.encoder().decodeFromBase64(property); + } catch (IOException e) { + throw new ConfigurationException("Incorrect type of : " + propertyName + ". Value " + property + + "cannot be converted to byte array", e); + } + } + + /** + * {@inheritDoc} + */ + @Override + public Boolean getBooleanProp(String propertyName) throws ConfigurationException { + String property = properties.getProperty(propertyName); + if (property == null) { + throw new ConfigurationException("Property : " + propertyName + "not found in default configuration"); + } + if (property.equalsIgnoreCase("true") || property.equalsIgnoreCase("yes")) { + return true; + } + if (property.equalsIgnoreCase("false") || property.equalsIgnoreCase("no")) { + return false; + } else { + throw new ConfigurationException("Incorrect type of : " + propertyName + ". Value " + property + + "cannot be converted to boolean"); + } + } + + /** + * {@inheritDoc} + */ + @Override + public String getStringProp(String propertyName) throws ConfigurationException { + String property = properties.getProperty(propertyName); + if (property == null) { + throw new ConfigurationException("Property : " + propertyName + "not found in default configuration"); + } + return property; + } + + /** + * Methods loads configuration from .properties file. + * @param file + */ + protected void loadPropertiesFromFile(File file) { + InputStream input = null; + try { + input = new FileInputStream(file); + properties.load(input); + } catch (IOException ex) { + logSpecial("Loading " + file.getName() + " via file I/O failed.", ex); + } finally { + if (input != null) { + try { + input.close(); + } catch (IOException e) { + logSpecial("Could not close stream"); + } + } + } + } + +} diff --git a/src/main/java/org/owasp/esapi/configuration/XmlEsapiPropertyLoader.java b/src/main/java/org/owasp/esapi/configuration/XmlEsapiPropertyLoader.java new file mode 100644 index 000000000..3b3dc8ebc --- /dev/null +++ b/src/main/java/org/owasp/esapi/configuration/XmlEsapiPropertyLoader.java @@ -0,0 +1,142 @@ +package org.owasp.esapi.configuration; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.errors.ConfigurationException; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.XMLConstants; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import javax.xml.validation.Validator; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +/** + * Loader capable of loading single security configuration property from xml configuration file. + * + * @since 2.2 + */ +public class XmlEsapiPropertyLoader extends AbstractPrioritizedPropertyLoader { + + public XmlEsapiPropertyLoader(String filename, int priority) throws IOException { + super(filename, priority); + } + + /** + * {@inheritDoc} + */ + @Override + public int getIntProp(String propertyName) throws ConfigurationException { + String property = properties.getProperty(propertyName); + if (property == null) { + throw new ConfigurationException("Property : " + propertyName + " not found in default configuration"); + } + try { + return Integer.parseInt(property); + } catch (NumberFormatException e) { + throw new ConfigurationException("Incorrect type of : " + propertyName + ". Value " + property + + "cannot be converted to integer", e); + } + } + + /** + * {@inheritDoc} + */ + @Override + public byte[] getByteArrayProp(String propertyName) throws ConfigurationException { + String property = properties.getProperty(propertyName); + if (property == null) { + throw new ConfigurationException("Property : " + propertyName + " not found in default configuration"); + } + try { + return ESAPI.encoder().decodeFromBase64(property); + } catch (IOException e) { + throw new ConfigurationException("Incorrect type of : " + propertyName + ". Value " + property + + "cannot be converted to byte array", e); + } + } + + /** + * {@inheritDoc} + */ + @Override + public Boolean getBooleanProp(String propertyName) throws ConfigurationException { + String property = properties.getProperty(propertyName); + if (property == null) { + throw new ConfigurationException("Property : " + propertyName + " not found in default configuration"); + } + if (property.equalsIgnoreCase("true") || property.equalsIgnoreCase("yes")) { + return true; + } + if (property.equalsIgnoreCase("false") || property.equalsIgnoreCase("no")) { + return false; + } else { + throw new ConfigurationException("Incorrect type of : " + propertyName + ". Value " + property + + "cannot be converted to boolean; legal values are: true, false, yes, no"); + } + } + + /** + * {@inheritDoc} + */ + @Override + public String getStringProp(String propertyName) throws ConfigurationException { + String property = properties.getProperty(propertyName); + if (property == null) { + throw new ConfigurationException("Property : " + propertyName + " not found in default configuration"); + } + return property; + } + + /** + * Methods loads configuration from .xml file. + * @param file + * @throws ConfigurationException if there is a problem loading the specified configuration file. + */ + protected void loadPropertiesFromFile(File file) throws ConfigurationException { + try ( InputStream configFile = new FileInputStream(file); ) { + validateAgainstXSD(configFile); + + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance("org.apache.xerces.jaxp.DocumentBuilderFactoryImpl", null); + dbFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + Document doc = dBuilder.parse(file); + doc.getDocumentElement().normalize(); + + NodeList nodeList = doc.getElementsByTagName("property"); + for (int i = 0; i < nodeList.getLength(); i++) { + Node node = nodeList.item(i); + if (node.getNodeType() == Node.ELEMENT_NODE) { + Element element = (Element) node; + String propertyKey = element.getAttribute("name"); + String propertyValue = element.getTextContent(); + properties.put(propertyKey, propertyValue); + } + } + } catch (IOException | SAXException | ParserConfigurationException e) { + logSpecial("XML config file " + filename + " doesn't exist or has invalid schema", e); + throw new ConfigurationException("Configuration file : " + filename + " has invalid schema." + + e.getMessage(), e); + } + } + + private void validateAgainstXSD(InputStream xml) throws IOException, SAXException { + try ( InputStream xsd = getClass().getResourceAsStream("/ESAPI-properties.xsd"); ) { + SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + Schema schema = factory.newSchema(new StreamSource(xsd)); + Validator validator = schema.newValidator(); + validator.validate(new StreamSource(xml)); + } + } + +} diff --git a/src/main/java/org/owasp/esapi/configuration/consts/EsapiConfiguration.java b/src/main/java/org/owasp/esapi/configuration/consts/EsapiConfiguration.java new file mode 100644 index 000000000..43df2fa1c --- /dev/null +++ b/src/main/java/org/owasp/esapi/configuration/consts/EsapiConfiguration.java @@ -0,0 +1,35 @@ +package org.owasp.esapi.configuration.consts; + +/** + * Enum used for initialization of esapi configuration files. + * + * @since 2.2 + */ +public enum EsapiConfiguration { + + OPSTEAM_ESAPI_CFG("org.owasp.esapi.opsteam", 1), + DEVTEAM_ESAPI_CFG("org.owasp.esapi.devteam", 2); + + /** + * Key of system property pointing to path esapi to configuration file. + */ + String configName; + + /** + * Priority of configuration (higher number - higher priority). + */ + int priority; + + EsapiConfiguration(String configName, int priority) { + this.configName = configName; + this.priority = priority; + } + + public String getConfigName() { + return configName; + } + + public int getPriority() { + return priority; + } +} diff --git a/src/main/java/org/owasp/esapi/configuration/consts/EsapiConfigurationType.java b/src/main/java/org/owasp/esapi/configuration/consts/EsapiConfigurationType.java new file mode 100644 index 000000000..b0112e1cf --- /dev/null +++ b/src/main/java/org/owasp/esapi/configuration/consts/EsapiConfigurationType.java @@ -0,0 +1,21 @@ +package org.owasp.esapi.configuration.consts; + + +/** + * Supported esapi configuration file types. + * + * @since 2.2 + */ +public enum EsapiConfigurationType { + PROPERTIES("properties"), XML("xml"); + + String typeName; + + EsapiConfigurationType(String typeName) { + this.typeName = typeName; + } + + public String getTypeName() { + return typeName; + } +} diff --git a/src/main/java/org/owasp/esapi/crypto/CipherSpec.java b/src/main/java/org/owasp/esapi/crypto/CipherSpec.java new file mode 100644 index 000000000..10b89b4d2 --- /dev/null +++ b/src/main/java/org/owasp/esapi/crypto/CipherSpec.java @@ -0,0 +1,417 @@ +/* + * 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) 2009 - The OWASP Foundation + */ +// If we had PRIVATE packages, e.g., org.owasp.esapi.util.pvt, this would belong +// there. CipherText uses this, but doesn't expose it directly. +package org.owasp.esapi.crypto; + +import java.io.Serializable; +import java.io.UnsupportedEncodingException; + +import javax.crypto.Cipher; +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.StringUtilities; +import org.owasp.esapi.util.NullSafe; + + +/** + * Specifies all the relevant configuration data needed in constructing and + * using a {@link javax.crypto.Cipher} except for the encryption key. + *

+ * The "setters" all return a reference to {@code this} so that they can be + * strung together. + *

+ * Note: While this is a useful class in it's own right, it should primarily be + * regarded as an implementation class to use with ESAPI encryption, especially + * the reference implementation. It is not intended to be used directly + * by application developers, but rather only by those either extending ESAPI + * or in the ESAPI reference implementation. Use directly by application + * code is not recommended or supported. + * + * @author kevin.w.wall@gmail.com + * @since 2.0 + */ +public final class CipherSpec implements Serializable { + + private static final long serialVersionUID = 20090822; // version, in YYYYMMDD format + + private String cipher_xform_ = ESAPI.securityConfiguration().getCipherTransformation(); + private int keySize_ = ESAPI.securityConfiguration().getEncryptionKeyLength(); // In bits + private int blockSize_ = 16; // In bytes! I.e., 128 bits!!! + private byte[] iv_ = null; + + private boolean blockSizeExplicitlySet = false; // Used for check in setIV(). + + // Cipher transformation component. Format is ALG/MODE/PADDING + private enum CipherTransformationComponent { ALG, MODE, PADDING } + + /** + * CTOR that explicitly sets everything. + * @param cipherXform The cipher transformation + * @param keySize The key size (in bits). + * @param blockSize The block size (in bytes). + * @param iv The initialization vector. Null if not applicable. + */ + public CipherSpec(String cipherXform, int keySize, int blockSize, final byte[] iv) { + setCipherTransformation(cipherXform); + setKeySize(keySize); + setBlockSize(blockSize); + setIV(iv); + } + + /** + * CTOR that sets everything but IV. + * @param cipherXform The cipher transformation + * @param keySize The key size (in bits). + * @param blockSize The block size (in bytes). + */ + public CipherSpec(String cipherXform, int keySize, int blockSize) { + // Note: Do NOT use + // this(cipherXform, keySize, blockSize, null); + // because of checks in setIV(). + // + setCipherTransformation(cipherXform); + setKeySize(keySize); + setBlockSize(blockSize); + } + + /** CTOR that sets everything but block size and IV. */ + public CipherSpec(String cipherXform, int keySize) { + setCipherTransformation(cipherXform); + setKeySize(keySize); + } + + /** CTOR that sets everything except block size. */ + public CipherSpec(String cipherXform, int keySize, final byte[] iv) { + setCipherTransformation(cipherXform); + setKeySize(keySize); + setIV(iv); + } + + /** CTOR that sets everything except for the cipher key size and possibly + * the IV. (IV may not be applicable--e.g., with ECB--or may not have + * been specified yet. + */ + public CipherSpec(final Cipher cipher) { + setCipherTransformation(cipher.getAlgorithm(), true); + setBlockSize(cipher.getBlockSize()); + if ( cipher.getIV() != null ) { + setIV(cipher.getIV()); + } + } + + /** CTOR that sets everything. */ + public CipherSpec(final Cipher cipher, int keySize) { + this(cipher); + setKeySize(keySize); + } + + /* CTOR that sets only the IV and uses defaults for everything else. */ + public CipherSpec(final byte[] iv) { + setIV(iv); + } + + /** + * Default CTOR. Creates a cipher specification for 128-bit cipher + * transformation of "AES/CBC/PKCS5Padding" and a {@code null} IV. + */ + public CipherSpec() { + // All defaults + } + + /** + * Set the cipher transformation for this {@code CipherSpec}. + * @param cipherXform The cipher transformation string; e.g., "DESede/CBC/PKCS5Padding". + * @return This current {@code CipherSpec} object. + */ + public CipherSpec setCipherTransformation(String cipherXform) { + setCipherTransformation(cipherXform, false); + return this; + } + + /** + * Set the cipher transformation for this {@code CipherSpec}. This is only + * used by the CTOR {@code CipherSpec(Cipher)} and {@code CipherSpec(Cipher, int)}. + * @param cipherXform The cipher transformation string; e.g., + * "DESede/CBC/PKCS5Padding". May not be null or empty. + * @param fromCipher If true, the cipher transformation was set via + * {@code Cipher.getAlgorithm()} which may only return the + * actual algorithm. In that case we check and if all 3 parts + * were not specified, then we specify the parts that were + * based on "ECB" as the default cipher mode and "NoPadding" + * as the default padding scheme. + * @return This current {@code CipherSpec} object. + */ + private CipherSpec setCipherTransformation(String cipherXform, boolean fromCipher) { + if ( ! StringUtilities.notNullOrEmpty(cipherXform, true) ) { // Yes, really want '!' here. + throw new IllegalArgumentException("Cipher transformation may not be null or empty string (after trimming whitespace)."); + } + int parts = cipherXform.split("/").length; + + // Assertion should be okay here as these conditions are checked + // elsewhere and this method is private. + assert ( !fromCipher ? (parts == 3) : true ) : + "Malformed cipherXform (" + cipherXform + "); must have form: \"alg/mode/paddingscheme\""; + if ( fromCipher && (parts != 3) ) { + // Indicates cipherXform was set based on Cipher.getAlgorithm() + // and thus may not be a *complete* cipher transformation. + if ( parts == 1 ) { + // Only algorithm was given. + cipherXform += "/ECB/NoPadding"; + } else if ( parts == 2 ) { + // Only algorithm and mode was given. + cipherXform += "/NoPadding"; + } else if ( parts == 3 ) { + // All three parts provided. Do nothing. Could happen if not compiled with + // assertions enabled, but there are explicit checks elsewhere. + ; // Do nothing - shown only for completeness. + } else { + // Should never happen unless Cipher implementation is totally screwed up. + throw new IllegalArgumentException("Cipher transformation '" + + cipherXform + "' must have form \"alg/mode/paddingscheme\""); + } + } else if ( !fromCipher && parts != 3 ) { + throw new IllegalArgumentException("Malformed cipherXform (" + cipherXform + + "); must have form: \"alg/mode/paddingscheme\""); + } + // Assertion should also be okay here as these conditions are checked + // elsewhere and this method is private. + assert cipherXform.split("/").length == 3 : "Implementation error setCipherTransformation()"; + this.cipher_xform_ = cipherXform; + return this; + } + + /** + * Get the cipher transformation. + * @return The cipher transformation {@code String}. + */ + public String getCipherTransformation() { + return cipher_xform_; + } + + /** + * Set the key size for this {@code CipherSpec}. + * @param keySize The key size, in bits. Must be positive integer. + * @return This current {@code CipherSpec} object. + */ + public CipherSpec setKeySize(int keySize) { + if ( keySize <= 0 ) { + throw new IllegalArgumentException("keySize must be > 0; keySize=" + keySize); + } + this.keySize_ = keySize; + return this; + } + + /** + * Retrieve the key size, in bits. + * @return The key size, in bits, is returned. + */ + public int getKeySize() { + return keySize_; + } + + /** + * Set the block size for this {@code CipherSpec}. + * @param blockSize The block size, in bytes. Must be positive integer appropriate + * for the specified cipher algorithm. + * @return This current {@code CipherSpec} object. + */ + public CipherSpec setBlockSize(int blockSize) { + if ( blockSize <= 0 ) { + throw new IllegalArgumentException("blockSize must be > 0; blockSize=" + blockSize); + } + this.blockSize_ = blockSize; + blockSizeExplicitlySet = true; + return this; + } + + /** + * Retrieve the block size, in bytes. + * @return The block size, in bytes, is returned. + */ + public int getBlockSize() { + return blockSize_; + } + + /** + * Retrieve the cipher algorithm. + * @return The cipher algorithm. + */ + public String getCipherAlgorithm() { + return getFromCipherXform(CipherTransformationComponent.ALG); + } + + /** + * Retrieve the cipher mode. + * @return The cipher mode. + */ + public String getCipherMode() { + return getFromCipherXform(CipherTransformationComponent.MODE); + } + + /** + * Retrieve the cipher padding scheme. + * @return The padding scheme is returned. + */ + public String getPaddingScheme() { + return getFromCipherXform(CipherTransformationComponent.PADDING); + } + + /** + * Retrieve the initialization vector (IV). + * @return The IV as a byte array. + */ + public byte[] getIV() { + return iv_; + } + + /** + * Set the initialization vector (IV). + * @param iv The byte array to set as the IV. A copy of the IV is saved. + * This parameter is ignored if the cipher mode does not + * require an IV. + * @return This current {@code CipherSpec} object. + */ + public CipherSpec setIV(final byte[] iv) { + if ( ! ( requiresIV() && (iv != null && iv.length != 0) ) ) { + throw new IllegalArgumentException("Required IV cannot be null or 0 length."); + } + + // Don't store a reference, but make a copy! When an IV is provided, it generally should + // be the same length as the block size of the cipher. + if ( iv != null ) { // Allow null IV for ECB mode. + // TODO: FIXME: As per email from Jeff Walton to Kevin Wall dated 12/03/2013, + // this is not always true. E.g., for CCM, the IV length is supposed + // to be 7, 8, 9, 10, 11, 12, or 13 octets because of + // it's formatting function. +/*** + if ( iv.length != this.getBlockSize() && blockSizeExplicitlySet ) { + throw new IllegalArgumentException("IV must be same length as cipher block size (" + + this.getBlockSize() + " bytes)"); + } +***/ + iv_ = new byte[ iv.length ]; + CryptoHelper.copyByteArray(iv, iv_); + } + return this; + } + + /** + * Return true if the cipher mode requires an IV. + * @return True if the cipher mode requires an IV, otherwise false. + * */ + public boolean requiresIV() { + + String cm = getCipherMode(); + + // Add any other cipher modes supported by JCE but not requiring IV. + // ECB is the only one I'm aware of that doesn't. Mode is not case + // sensitive. + if ( "ECB".equalsIgnoreCase(cm) ) { + return false; + } + return true; + } + + /** + * Override {@code Object.toString()} to provide something more useful. + * @return A meaningful string describing this object. + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder("CipherSpec: "); + sb.append( getCipherTransformation() ).append("; keysize= ").append( getKeySize() ); + sb.append(" bits; blocksize= ").append( getBlockSize() ).append(" bytes"); + byte[] iv = getIV(); + String ivLen = null; + if ( iv != null ) { + ivLen = "" + iv.length; // Convert length to a string + } else { + ivLen = "[No IV present (not set or not required)]"; + } + sb.append("; IV length = ").append( ivLen ).append(" bytes."); + return sb.toString(); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object other) { + boolean result = false; + if ( this == other ) + return true; + if ( other == null ) + return false; + if ( other instanceof CipherSpec) { + CipherSpec that = (CipherSpec)other; + result = (that.canEqual(this) && + NullSafe.equals(this.cipher_xform_, that.cipher_xform_) && + this.keySize_ == that.keySize_ && + this.blockSize_ == that.blockSize_ && + // In all versions of JDK 7 and later, comparison safe from timing attacks. + java.security.MessageDigest.isEqual(this.iv_, that.iv_) ); + } + return result; + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + StringBuilder sb = new StringBuilder(); + sb.append( getCipherTransformation() ); + sb.append( "" + getKeySize() ); + sb.append( "" + getBlockSize() ); + byte[] iv = getIV(); + if ( iv != null && iv.length > 0 ) { + String ivStr = null; + try { + ivStr = new String(iv, "UTF-8"); + } + catch(UnsupportedEncodingException ex) { + // Should never happen as UTF-8 encode supported by rt.jar, + // but it it does, just use default encoding. + ivStr = new String(iv); + } + sb.append( ivStr ); + } + return sb.toString().hashCode(); + } + + /** + * Needed for correct definition of equals for general classes. + * (Technically not needed for 'final' classes like this class though; this + * will just allow it to work in the future should we decide to allow + * sub-classing of this class.) + *

+ * See + * How to write an Equality Method in Java + * for full explanation. + *

+ */ + protected boolean canEqual(Object other) { + return (other instanceof CipherSpec); + } + + /** + * Split the current cipher transformation and return the requested part. + * @param component The component of the cipher transformation to return. + * @return The cipher algorithm, cipher mode, or padding, as requested. + */ + private String getFromCipherXform(CipherTransformationComponent component) { + int part = component.ordinal(); + String[] parts = getCipherTransformation().split("/"); + // Assertion should also be okay here as these conditions are checked + // elsewhere and this method is private. + assert parts.length == 3 : "Invalid cipher transformation: " + getCipherTransformation(); + return parts[part]; + } +} diff --git a/src/main/java/org/owasp/esapi/crypto/CipherText.java b/src/main/java/org/owasp/esapi/crypto/CipherText.java new file mode 100644 index 000000000..185ac5e14 --- /dev/null +++ b/src/main/java/org/owasp/esapi/crypto/CipherText.java @@ -0,0 +1,928 @@ +/* + * 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 © 2009 - The OWASP Foundation + */ +package org.owasp.esapi.crypto; + + +import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.util.Date; +import java.util.EnumSet; +import java.util.Iterator; + +import javax.crypto.Mac; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Encryptor; +import org.owasp.esapi.Logger; +import org.owasp.esapi.errors.EncryptionException; +import org.owasp.esapi.errors.EnterpriseSecurityRuntimeException; + +// CHECKME: Some of these assertions probably should be actual runtime checks +// with suitable exceptions to account for cases where programmers +// accidentally pass in byte arrays that are not really serialized +// CipherText objects (note: as per asPortableSerializedByteArra()). +// However, not sure what exception time is really suitable here. +// It probably should be a sub-class of RuntimeException, but +// IllegalArguementException doesn't really make sense here. Suggestions? + +/** + * A {@code Serializable} interface representing the result of encrypting + * plaintext and some additional information about the encryption algorithm, + * the IV (if pertinent), and an optional Message Authentication Code (MAC). + *

+ * Note that while this class is {@code Serializable} in the usual Java sense, + * ESAPI uses {@link #asPortableSerializedByteArray()} for serialization. Not + * only is this serialization somewhat more compact, it is also portable + * across other ESAPI programming language implementations. However, Java + * serialization is supported in the event that one wishes to store + * {@code CipherText} in an {@code HttpSession} object. + *

+ * Copyright © 2009 - The OWASP Foundation + *

+ * @author kevin.w.wall@gmail.com + * @see PlainText + * @see org.owasp.esapi.Encryptor + * @since 2.0 + */ +public final class CipherText implements Serializable { + // NOTE: Do NOT change this in future versions, unless you are knowingly + // making changes to the class that will render this class incompatible + // with previously serialized objects from older versions of this class. + // If this is done, that you must provide for supporting earlier ESAPI versions. + // Be wary making incompatible changes as discussed at: + // http://java.sun.com/javase/6/docs/platform/serialization/spec/version.html#6678 + // Any incompatible change in the serialization of CipherText *must* be + // reflected in the class CipherTextSerializer. + // This should be *same* version as in CipherTextSerializer and KeyDerivationFunction. + // If one changes, the other should as well to accommodate any differences. + // Previous versions: 20110203 - Original version (ESAPI releases 2.0 & 2.0.1) + // 20130830 - Fix to issue #306 (release 2.1.0) + public static final int cipherTextVersion = 20130830; // Format: YYYYMMDD, max is 99991231. + // Required by Serializable classes. + private static final long serialVersionUID = cipherTextVersion; // Format: YYYYMMDD + + private static final Logger logger = ESAPI.getLogger("CipherText"); + + private CipherSpec cipherSpec_ = null; + private byte[] raw_ciphertext_ = null; + private byte[] separate_mac_ = null; + private long encryption_timestamp_ = 0; + private int kdfVersion_ = KeyDerivationFunction.kdfVersion; + private int kdfPrfSelection_ = KeyDerivationFunction.getDefaultPRFSelection(); + + // All the various pieces that can be set, either directly or indirectly + // via CipherSpec. + private enum CipherTextFlags { + ALGNAME, CIPHERMODE, PADDING, KEYSIZE, BLOCKSIZE, CIPHERTEXT, INITVECTOR + } + + // If we have everything set, we compare it to this using '==' which javac + // specially overloads for this. + private final EnumSet allCtFlags = + EnumSet.of(CipherTextFlags.ALGNAME, CipherTextFlags.CIPHERMODE, + CipherTextFlags.PADDING, CipherTextFlags.KEYSIZE, + CipherTextFlags.BLOCKSIZE, CipherTextFlags.CIPHERTEXT, + CipherTextFlags.INITVECTOR); + + // These are all the pieces we collect when passed a CipherSpec object. + private final EnumSet fromCipherSpec = + EnumSet.of(CipherTextFlags.ALGNAME, CipherTextFlags.CIPHERMODE, + CipherTextFlags.PADDING, CipherTextFlags.KEYSIZE, + CipherTextFlags.BLOCKSIZE); + + // How much we've collected so far. We start out with having collected nothing. + private EnumSet progress = EnumSet.noneOf(CipherTextFlags.class); + + // Check if versions of KeyDerivationFunction, CipherText, and + // CipherTextSerializer are all the same. + { + // Ignore error about comparing identical versions and dead code. + // We expect them to be, but the point is to catch us if they aren't. + if ( CipherTextSerializer.cipherTextSerializerVersion != CipherText.cipherTextVersion ) { + throw new ExceptionInInitializerError("Versions of CipherTextSerializer and CipherText are not compatible."); + } + if ( CipherTextSerializer.cipherTextSerializerVersion != KeyDerivationFunction.kdfVersion ) { + throw new ExceptionInInitializerError("Versions of CipherTextSerializer and KeyDerivationFunction are not compatible."); + } + } + + /////////////////////////// C O N S T R U C T O R S ///////////////////////// + + /** + * Default CTOR. Takes all the defaults from the ESAPI.properties, or + * default values from initial values from this class (when appropriate) + * when they are not set in ESAPI.properties. + */ + public CipherText() { + cipherSpec_ = new CipherSpec(); // Uses default for everything but IV. + received(fromCipherSpec); + } + + /** + * Construct from a {@code CipherSpec} object. Still needs to have + * {@link #setCiphertext(byte[])} or {@link #setIVandCiphertext(byte[], byte[])} + * called to be usable. + * + * @param cipherSpec The cipher specification to use. + */ + public CipherText(final CipherSpec cipherSpec) { + cipherSpec_ = cipherSpec; + received(fromCipherSpec); + if ( cipherSpec.getIV() != null ) { + received(CipherTextFlags.INITVECTOR); + } + } + + /** + * Construct from a {@code CipherSpec} object and the raw ciphertext. + * + * @param cipherSpec The cipher specification to use. + * @param cipherText The raw ciphertext bytes to use. + * @throws EncryptionException Thrown if {@code cipherText} is null or + * empty array. + */ + public CipherText(final CipherSpec cipherSpec, byte[] cipherText) + throws EncryptionException + { + cipherSpec_ = cipherSpec; + setCiphertext(cipherText); + received(fromCipherSpec); + if ( cipherSpec.getIV() != null ) { + received(CipherTextFlags.INITVECTOR); + } + } + + /** Create a {@code CipherText} object from what is supposed to be a + * portable serialized byte array, given in network byte order, that + * represents a valid, previously serialized {@code CipherText} object + * using {@link #asPortableSerializedByteArray()}. + * @param bytes A byte array created via + * {@code CipherText.asPortableSerializedByteArray()} + * @return A {@code CipherText} object reconstructed from the byte array. + * @throws EncryptionException + * @see #asPortableSerializedByteArray() + */ // DISCUSS: BTW, I detest this name. Suggestions??? + public static CipherText fromPortableSerializedBytes(byte[] bytes) + throws EncryptionException + { + CipherTextSerializer cts = new CipherTextSerializer(bytes); + return cts.asCipherText(); + } + + ///////////////////////// P U B L I C M E T H O D S //////////////////// + + /** + * Obtain the String representing the cipher transformation used to encrypt + * the plaintext. The cipher transformation represents the cipher algorithm, + * the cipher mode, and the padding scheme used to do the encryption. An + * example would be "AES/CBC/PKCS5Padding". See Appendix A in the + * + * Java Cryptography Architecture Reference Guide + * for information about standard supported cipher transformation names. + *

+ * The cipher transformation name is usually sufficient to be passed to + * {@link javax.crypto.Cipher#getInstance(String)} to create a + * Cipher object to decrypt the ciphertext. + * + * @return The cipher transformation name used to encrypt the plaintext + * resulting in this ciphertext. + */ + public String getCipherTransformation() { + return cipherSpec_.getCipherTransformation(); + } + + /** + * Obtain the name of the cipher algorithm used for encrypting the + * plaintext. + * + * @return The name as the cryptographic algorithm used to perform the + * encryption resulting in this ciphertext. + */ + public String getCipherAlgorithm() { + return cipherSpec_.getCipherAlgorithm(); + } + + /** + * Retrieve the key size used with the cipher algorithm that was used to + * encrypt data to produce this ciphertext. + * + * @return The key size in bits. We work in bits because that's the crypto way! + */ + public int getKeySize() { + return cipherSpec_.getKeySize(); + } + + /** + * Retrieve the block size (in bytes!) of the cipher used for encryption. + * (Note: If an IV is used, this will also be the IV length.) + * + * @return The block size in bytes. (Bits, bytes! It's confusing I know. Blame + * the cryptographers; we've just following + * convention.) + */ + public int getBlockSize() { + return cipherSpec_.getBlockSize(); + } + + /** + * Get the name of the cipher mode used to encrypt some plaintext. + * + * @return The name of the cipher mode used to encrypt the plaintext + * resulting in this ciphertext. E.g., "CBC" for "cipher block + * chaining", "ECB" for "electronic code book", etc. + */ + public String getCipherMode() { + return cipherSpec_.getCipherMode(); + } + + /** + * Get the name of the padding scheme used to encrypt some plaintext. + * + * @return The name of the padding scheme used to encrypt the plaintext + * resulting in this ciphertext. Example: "PKCS5Padding". If no + * padding was used "None" is returned. + */ + public String getPaddingScheme() { + return cipherSpec_.getPaddingScheme(); + } + + /** + * Return the initialization vector (IV) used to encrypt the plaintext + * if applicable. + * + * @return The IV is returned if the cipher mode used to encrypt the + * plaintext was not "ECB". ECB mode does not use an IV so in + * that case, null is returned. + */ + public byte[] getIV() { + if ( isCollected(CipherTextFlags.INITVECTOR) ) { + return cipherSpec_.getIV(); + } else { + logger.error(Logger.SECURITY_FAILURE, "IV not set yet; unable to retrieve; returning null"); + return null; + } + } + + /** + * Return true if the cipher mode used requires an IV. Usually this will + * be true unless ECB mode (which should be avoided whenever possible) is + * used. + */ + public boolean requiresIV() { + return cipherSpec_.requiresIV(); + } + + /** + * Get the raw ciphertext byte array resulting from encrypting some + * plaintext. + * + * @return A copy of the raw ciphertext as a byte array. + */ + public byte[] getRawCipherText() { + if ( isCollected(CipherTextFlags.CIPHERTEXT) ) { + byte[] copy = new byte[ raw_ciphertext_.length ]; + System.arraycopy(raw_ciphertext_, 0, copy, 0, raw_ciphertext_.length); + return copy; + } else { + logger.error(Logger.SECURITY_FAILURE, "Raw ciphertext not set yet; unable to retrieve; returning null"); + return null; + } + } + + /** + * Get number of bytes in raw ciphertext. Zero is returned if ciphertext has not + * yet been stored. + * + * @return The number of bytes of raw ciphertext; 0 if no raw ciphertext has been stored. + */ + public int getRawCipherTextByteLength() { + if ( raw_ciphertext_ != null ) { + return raw_ciphertext_.length; + } else { + return 0; + } + } + + /** + * Return a base64-encoded representation of the raw ciphertext alone. Even + * in the case where an IV is used, the IV is not prepended before the + * base64-encoding is performed. + *

+ * If there is a need to store an encrypted value, say in a database, this + * is not the method you should use unless you are using are storing the + * IV separately (i.e., in a separate DB column), which doesn't make a lot of sense. + * Normally, you should prefer the method {@link #getEncodedIVCipherText()} instead as + * it will return the IV prepended to the ciphertext. + *

+ * @see #getEncodedIVCipherText() + */ + public String getBase64EncodedRawCipherText() { + return ESAPI.encoder().encodeForBase64(getRawCipherText(),false); + } + + /** + * Return the ciphertext as a base64-encoded String. If an + * IV was used, the IV if first prepended to the raw ciphertext before + * base64-encoding. If an IV is not used, then this method returns the same + * value as {@link #getBase64EncodedRawCipherText()}. + *

+ * @return The base64-encoded ciphertext or base64-encoded IV + ciphertext. + * @see #getBase64EncodedRawCipherText() + */ + public String getEncodedIVCipherText() { + if ( isCollected(CipherTextFlags.INITVECTOR) && isCollected(CipherTextFlags.CIPHERTEXT) ) { + // First concatenate IV + raw ciphertext + byte[] iv = getIV(); + byte[] raw = getRawCipherText(); + byte[] ivPlusCipherText = new byte[ iv.length + raw.length ]; + System.arraycopy(iv, 0, ivPlusCipherText, 0, iv.length); + System.arraycopy(raw, 0, ivPlusCipherText, iv.length, raw.length); + // Then return the base64 encoded result + return ESAPI.encoder().encodeForBase64(ivPlusCipherText, false); + } else { + logger.error(Logger.SECURITY_FAILURE, "Raw ciphertext and/or IV not set yet; unable to retrieve; returning null"); + return null; + } + } + + /** + * Compute and store the Message Authentication Code (MAC) if the ESAPI property + * {@code Encryptor.CipherText.useMAC} is set to {@code true}. If it + * is, the MAC is conceptually calculated as: + *

+     *      authKey = DerivedKey(secret_key, "authenticate")
+     *      HMAC-SHA1(authKey, IV + secret_key)
+     * 
+ * where derived key is an HMacSHA1, possibly repeated multiple times. + * (See {@link org.owasp.esapi.crypto.CryptoHelper#computeDerivedKey(SecretKey, int, String)} + * for details.) + *

+ * Perceived Benefits: There are certain cases where if an attacker + * is able to change the IV. When one uses a authenticity key that is + * derived from the "master" key, it also makes it possible to know when + * the incorrect key was attempted to be used to decrypt the ciphertext. + *

+ * NOTE: The purpose of this MAC (which is always computed by the + * ESAPI reference model implementing {@code Encryptor}) is to ensure the + * authenticity of the IV and ciphertext. Among other things, this prevents + * an adversary from substituting the IV with one of their own choosing. + * Because we don't know whether or not the recipient of this {@code CipherText} + * object will want to validate the authenticity or not, the reference + * implementation of {@code Encryptor} always computes it and includes it. + * The recipient of the ciphertext can then choose whether or not to validate + * it. + * + * @param authKey The secret key that is used for proving authenticity of + * the IV and ciphertext. This key should be derived from + * the {@code SecretKey} passed to the + * {@link Encryptor#encrypt(javax.crypto.SecretKey, PlainText)} + * and + * {@link Encryptor#decrypt(javax.crypto.SecretKey, CipherText)} + * methods or the "master" key when those corresponding + * encrypt / decrypt methods are used. This authenticity key + * should be the same length and for the same cipher algorithm + * as this {@code SecretKey}. The method + * {@link org.owasp.esapi.crypto.CryptoHelper#computeDerivedKey(SecretKey, int, String)} + * is a secure way to produce this derived key. + */ // DISCUSS - Cryptographers David Wagner, Ian Grigg, and others suggest + // computing authenticity using derived key and HmacSHA1 of IV + ciphertext. + // However they also argue that what should be returned and treated as + // (i.e., stored as) ciphertext would be something like this: + // len_of_raw_ciphertext + IV + raw_ciphertext + MAC + // However, Schneier's & Ferguson's Horton Principle would argue + // that whatever data that one sends needs to be authenticated, so + // that would minimally mean that len_of_raw_ciphertext would need + // to be included in the MAC calculation. Failure to heed the Horton + // Principle has already resulted in CVE-2013-5960. + // + // TODO: Need to do something like this for custom serialization and then + // document order / format so it can be used by other ESAPI implementations. + public void computeAndStoreMAC(SecretKey authKey) { + if ( macComputed() ) { + String exm = "Programming error: Can't store message authentication code " + + "while encrypting; computeAndStoreMAC() called multiple times."; + throw new EnterpriseSecurityRuntimeException(exm, exm); + } + if ( ! collectedAll() ) { + String exm = "Have not collected all required information to compute and store MAC."; + throw new EnterpriseSecurityRuntimeException(exm, exm); + } + byte[] result = computeMAC(authKey); + if ( result != null ) { + storeSeparateMAC(result); + } + // If 'result' is null, we already logged this in computeMAC(). + } + + /** + * Same as {@link #computeAndStoreMAC(SecretKey)} but this is only used by + * {@code CipherTextSerializeer}. (Has package level access.) + */ // CHECKME: For this to be "safe", it requires ESAPI jar to be sealed. + void storeSeparateMAC(byte[] macValue) { + if ( !macComputed() ) { + separate_mac_ = new byte[ macValue.length ]; + CryptoHelper.copyByteArray(macValue, separate_mac_); + // This assertion should be okay as it's just a sanity check. + assert macComputed() : "MAC failed to compute correctly!"; + } + } + + /** + * Validate the message authentication code (MAC) associated with the ciphertext. + * This is mostly meant to ensure that an attacker has not replaced the IV + * or raw ciphertext with something arbitrary. Note however that it will + * not detect the case where an attacker simply substitutes one + * valid ciphertext with another ciphertext. + * + * @param authKey The secret key that is used for proving authenticity of + * the IV and ciphertext. This key should be derived from + * the {@code SecretKey} passed to the + * {@link Encryptor#encrypt(javax.crypto.SecretKey, PlainText)} + * and + * {@link Encryptor#decrypt(javax.crypto.SecretKey, CipherText)} + * methods or the "master" key when those corresponding + * encrypt / decrypt methods are used. This authenticity key + * should be the same length and for the same cipher algorithm + * as this {@code SecretKey}. The method + * {@link org.owasp.esapi.crypto.CryptoHelper#computeDerivedKey(SecretKey, int, String)} + * is a secure way to produce this derived key. + * @return True if the ciphertext has not be tampered with, and false otherwise. + */ + public boolean validateMAC(SecretKey authKey) { + boolean requiresMAC = ESAPI.securityConfiguration().useMACforCipherText(); + + if ( requiresMAC && macComputed() ) { // Uses MAC and it was computed + // Calculate MAC from HMAC-SHA1(nonce, IV + plaintext) and + // compare to stored value (separate_mac_). If same, then return true, + // else return false. + byte[] mac = computeMAC(authKey); + if ( mac.length != separate_mac_.length ) { + // Note: We want some type of unchecked exception + // here so this will not require code changes. + // Unfortunately, EncryptionException, which might + // make more sense here, is not a RuntimeException. + String exm = "MACs are of different lengths. " + + "Should both be the same length"; + throw new EnterpriseSecurityRuntimeException(exm, + "Possible tampering of MAC? " + exm + + "computed MAC len: " + mac.length + + ", received MAC len: " + separate_mac_.length); + } + return java.security.MessageDigest.isEqual(mac, separate_mac_); // Safe compare in JDK 7 and later + } else if ( ! requiresMAC ) { // Doesn't require a MAC + return true; + } else { + // This *used* to be the case (for versions 2.0 and 2.0.1) where we tried to + // accomodate the deprecated decrypt() method from ESAPI 1.4. Unfortunately, + // that was an EPIC FAIL. (See Google Issue # 306 for details.) + logger.warning(Logger.SECURITY_FAILURE, "MAC may have been tampered with (e.g., length set to 0)."); + return false; // Deprecated decrypt() method removed, so now return false. + } + } + + /** + * Return this {@code CipherText} object as a portable (i.e., network byte + * ordered) serialized byte array. Note this is not the same as + * returning a serialized object using Java serialization. Instead, this + * is a representation that all ESAPI implementations will use to pass + * ciphertext between different programming language implementations. + * + * @return A network byte-ordered serialized representation of this object. + * @throws EncryptionException + */ // DISCUSS: This method name sucks too. Suggestions??? + public byte[] asPortableSerializedByteArray() throws EncryptionException { + // Check if this CipherText object is "complete", i.e., all + // mandatory has been collected. + if ( ! collectedAll() ) { + String msg = "Can't serialize this CipherText object yet as not " + + "all mandatory information has been collected"; + throw new EncryptionException("Can't serialize incomplete ciphertext info", msg); + } + + // If we are supposed to be using a (separate) MAC, also make sure + // that it has been computed/stored. + boolean requiresMAC = ESAPI.securityConfiguration().useMACforCipherText(); + if ( requiresMAC && ! macComputed() ) { + String msg = "Programming error: MAC is required for this cipher mode (" + + getCipherMode() + "), but MAC has not yet been " + + "computed and stored. Call the method " + + "computeAndStoreMAC(SecretKey) first before " + + "attempting serialization."; + throw new EncryptionException("Can't serialize ciphertext info: Data integrity issue.", + msg); + } + + // OK, everything ready, so give it a shot. + return new CipherTextSerializer(this).asSerializedByteArray(); + } + + ///// Setters ///// + /** + * Set the raw ciphertext. + * @param ciphertext The raw ciphertext. + * @throws EncryptionException Thrown if the MAC has already been computed + * via {@link #computeAndStoreMAC(SecretKey)}. + */ + public void setCiphertext(byte[] ciphertext) + throws EncryptionException + { + if ( ! macComputed() ) { + if ( ciphertext == null || ciphertext.length == 0 ) { + throw new EncryptionException("Encryption faled; no ciphertext", + "Ciphertext may not be null or 0 length!"); + } + if ( isCollected(CipherTextFlags.CIPHERTEXT) ) { + logger.warning(Logger.SECURITY_FAILURE, "Raw ciphertext was already set; resetting."); + } + raw_ciphertext_ = new byte[ ciphertext.length ]; + CryptoHelper.copyByteArray(ciphertext, raw_ciphertext_); + received(CipherTextFlags.CIPHERTEXT); + setEncryptionTimestamp(); + } else { + String logMsg = "Programming error: Attempt to set ciphertext after MAC already computed."; + logger.error(Logger.SECURITY_FAILURE, logMsg); + throw new EncryptionException("MAC already set; cannot store new raw ciphertext", logMsg); + } + } + + /** + * Set the IV and raw ciphertext. + * @param iv The initialization vector. + * @param ciphertext The raw ciphertext. + * @throws EncryptionException + */ + public void setIVandCiphertext(byte[] iv, byte[] ciphertext) + throws EncryptionException + { + if ( isCollected(CipherTextFlags.INITVECTOR) ) { + logger.warning(Logger.SECURITY_FAILURE, "IV was already set; resetting."); + } + if ( isCollected(CipherTextFlags.CIPHERTEXT) ) { + logger.warning(Logger.SECURITY_FAILURE, "Raw ciphertext was already set; resetting."); + } + if ( ! macComputed() ) { + if ( ciphertext == null || ciphertext.length == 0 ) { + throw new EncryptionException("Encryption faled; no ciphertext", + "Ciphertext may not be null or 0 length!"); + } + if ( iv == null || iv.length == 0 ) { + if ( requiresIV() ) { + throw new EncryptionException("Encryption failed -- mandatory IV missing", // DISCUSS - also log? See below. + "Cipher mode " + getCipherMode() + " has null or empty IV"); + } + } else if ( iv.length != getBlockSize() ) { +// TODO: FIXME: As per email from Jeff Walton to Kevin Wall dated 12/03/2013, +// this is not always true. E.g., for CCM, the IV length is supposed +// to be 7, 8, 7, 8, 9, 10, 11, 12, or 13 octets because of +// it's formatting function, the rest of the octets are used by the +// nonce/counter. E.g., see RFCs 4309, 8750, and related RFCs. + throw new EncryptionException("Encryption failed -- bad parameters passed to encrypt", // DISCUSS - also log? See below. + "IV length does not match cipher block size of " + getBlockSize()); + } + cipherSpec_.setIV(iv); + received(CipherTextFlags.INITVECTOR); + setCiphertext( ciphertext ); + } else { + String logMsg = "MAC already computed from previously set IV and raw ciphertext; may not be reset -- object is immutable."; + logger.error(Logger.SECURITY_FAILURE, logMsg); // Discuss: By throwing, this gets logged as warning, but it's really error! Why is an exception only a warning??? + throw new EncryptionException("Validation of decryption failed.", logMsg); + } + } + + public int getKDFVersion() { + return kdfVersion_; + } + + public void setKDFVersion(int vers) { + CryptoHelper.isValidKDFVersion(vers, false, true); + kdfVersion_ = vers; + } + + public KeyDerivationFunction.PRF_ALGORITHMS getKDF_PRF() { + return KeyDerivationFunction.convertIntToPRF(kdfPrfSelection_); + } + + int kdfPRFAsInt() { + return kdfPrfSelection_; + } + + public void setKDF_PRF(int prfSelection) { + if ( prfSelection < 0 || prfSelection > 15 ) { + throw new IllegalArgumentException("kdfPrf == " + prfSelection + " must be between 0 and 15, inclusive."); + } + kdfPrfSelection_ = prfSelection; + } + + /** Get stored time stamp representing when data was encrypted. */ + public long getEncryptionTimestamp() { + return encryption_timestamp_; + } + + /** + * Set the encryption timestamp to the current system time as determined by + * {@code System.currentTimeMillis()}, but only if it has not been previously + * set. That is, this method ony has an effect the first time that it is + * called for this object. + */ + private void setEncryptionTimestamp() { + // We want to skip this when it's already been set via the package + // level call setEncryptionTimestamp(long) done via CipherTextSerializer + // otherwise it gets reset to the current time. But when it's restored + // from a serialized CipherText object, we want to keep the original + // encryption timestamp. + if ( encryption_timestamp_ != 0 ) { + logger.warning(Logger.EVENT_FAILURE, "Attempt to reset non-zero " + + "CipherText encryption timestamp to current time!"); + } + encryption_timestamp_ = System.currentTimeMillis(); + } + + /** + * Set the encryption timestamp to the time stamp specified by the parameter. + *

+ * This method is intended for use only by {@code CipherTextSerializer}. + * + * @param timestamp The time in milliseconds since epoch time (midnight, + * January 1, 1970 GMT). + */ // Package level access. ESAPI jar should be sealed and signed. + void setEncryptionTimestamp(long timestamp) { + if ( timestamp <= 0 ) { + throw new IllegalArgumentException("Timestamp must be greater than zero."); + } + if ( encryption_timestamp_ == 0 ) { // Only set it if it's not yet been set. + logger.warning(Logger.EVENT_FAILURE, "Attempt to reset non-zero " + + "CipherText encryption timestamp to " + new Date(timestamp) + "!"); + } + encryption_timestamp_ = timestamp; + } + + /** Return the separately calculated Message Authentication Code (MAC) that + * is computed via the {@code computeAndStoreMAC(SecretKey authKey)} method. + * @return The copy of the computed MAC, or {@code null} if one is not used. + */ + public byte[] getSeparateMAC() { + if ( separate_mac_ == null ) { + return null; + } + byte[] copy = new byte[ separate_mac_.length ]; + System.arraycopy(separate_mac_, 0, copy, 0, separate_mac_.length); + return copy; + } + + /** + * More useful {@code toString()} method. + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder( "CipherText: " ); + String creationTime = (( getEncryptionTimestamp() == 0) ? "No timestamp available" : + (new Date(getEncryptionTimestamp())).toString()); + int n = getRawCipherTextByteLength(); + String rawCipherText = (( n > 0 ) ? "present (" + n + " bytes)" : "absent"); + String mac = (( separate_mac_ != null ) ? "present" : "absent"); + + sb.append("KDF Version: ").append( kdfVersion_ ); + sb.append(", KDF PRF: ").append( kdfPRFAsInt() ); + sb.append("; Creation time: ").append(creationTime); + sb.append("; raw ciphertext is ").append(rawCipherText); + sb.append("; MAC is ").append(mac).append("; "); + sb.append( cipherSpec_.toString() ); + return sb.toString(); + } + + /** + * {@inheritDoc} + */ + @Override public boolean equals(Object other) { + boolean result = false; + if ( this == other ) + return true; + if ( other == null ) + return false; + if ( other instanceof CipherText) { + CipherText that = (CipherText)other; + if ( this.collectedAll() && that.collectedAll() ) { + result = (that.canEqual(this) && + this.cipherSpec_.equals(that.cipherSpec_) && + // Safe comparison, resistant to timing attacks + java.security.MessageDigest.isEqual(this.raw_ciphertext_, that.raw_ciphertext_) && + java.security.MessageDigest.isEqual(this.separate_mac_, that.separate_mac_) && + this.encryption_timestamp_ == that.encryption_timestamp_ ); + } else { + logger.warning(Logger.EVENT_FAILURE, "CipherText.equals(): Cannot compare two " + + "CipherText objects that are not complete, and therefore immutable!"); + logger.info(Logger.EVENT_FAILURE, "This CipherText: " + this.collectedAll() + ";" + + "other CipherText: " + that.collectedAll()); + logger.info(Logger.EVENT_FAILURE, "CipherText.equals(): Progress comparison: " + + ((this.progress == that.progress) ? "Same" : "Different")); + logger.info(Logger.EVENT_FAILURE, "CipherText.equals(): Status this: " + this.progress + + "; status other CipherText object: " + that.progress); + // CHECKME: Perhaps we should throw a RuntimeException instead??? + return false; + } + } + return result; + } + + /** + * {@inheritDoc} + */ + @Override public int hashCode() { + if ( this.collectedAll() ) { + logger.warning(Logger.EVENT_FAILURE, "CipherText.hashCode(): Cannot compute " + + "hachCode() of incomplete CipherText object; object not immutable- " + + "returning 0."); + // CHECKME: Throw RuntimeException instead? + return 0; + } + StringBuilder sb = new StringBuilder(); + sb.append( cipherSpec_.hashCode() ); + sb.append( encryption_timestamp_ ); + String raw_ct = null; + String mac = null; + try { + raw_ct = new String(raw_ciphertext_, "UTF-8"); + // Remember, MAC is optional even when CipherText is complete. + mac = new String( ((separate_mac_ != null) ? separate_mac_ : new byte[] { }), "UTF-8"); + } catch(UnsupportedEncodingException ex) { + // Should never happen as UTF-8 encode supported by rt.jar, + // but it it does, just use default encoding. + raw_ct = new String(raw_ciphertext_); + mac = new String( ((separate_mac_ != null) ? separate_mac_ : new byte[] { })); + } + sb.append( raw_ct ); + sb.append( mac ); + return sb.toString().hashCode(); + } + + /** + * Needed for correct definition of equals for general classes. + * (Technically not needed for 'final' classes though like this class + * though; this will just allow it to work in the future should we + * decide to allow * sub-classing of this class.) + *

+ * See + * @link http://www.artima.com/lejava/articles/equality.html + * for full explanation. + *

+ */ + protected boolean canEqual(Object other) { + return (other instanceof CipherText); + } + + //////////////////////////////////// P R I V A T E ///////////////////////////////////////// + + /** + * Compute a MAC, but do not store it. May set the nonce value as a + * side-effect. The MAC is calculated as: + *
+     *      HMAC-SHA1(nonce, IV + plaintext)
+     * 
+ * Note that only HMAC-SHA1 is used for the MAC calcuation. Unlike + * the PRF used for derived key generation in the {@code KeyDerivationFunction} + * class, the user cannot change the algorithm used to compute the MAC itself. + * One reason for that is that we don't want the MAC value to be excessively + * long; 128 bits is already quite long when only encrypting short strings. + * Also while the NSA reviewed this and were okay with it, Bellare, Canetti & Krawczyk + * proved in 1996 [see http://pssic.free.fr/Extra%20Reading/SEC+/SEC+/hmac-cb.pdf] that + * HMAC security doesn’t require that the underlying hash function be collision resistant, + * but only that it acts as a pseudo-random function, which SHA1 satisfies. + * @param authKey The {@code SecretKey} used with the computed HMAC-SHA1 + * to ensure authenticity. + * @return The value for the MAC. + */ + private byte[] computeMAC(SecretKey authKey) { + // These assertions are okay and leaving them as assertions rather than + // changing the to conditional statements that throw should be all right + // because this is private method and presumably we should have already + // checked things in the public or protected methods where appropriate. + if ( raw_ciphertext_ == null || raw_ciphertext_.length == 0 ) { + String exm = "Raw ciphertext may not be null or empty."; + throw new EnterpriseSecurityRuntimeException(exm, exm); + } + if ( authKey == null || authKey.getEncoded().length == 0 ) { + String exm = "Authenticity secret key may not be null or zero length."; + throw new EnterpriseSecurityRuntimeException(exm, exm); + } + + try { + // IMPORTANT NOTE: The NSA review was (apparently) OK with using HmacSHA1 + // to calculate the MAC that ensures authenticity of the IV+ciphertext. + // (Not true of calculation of the use HmacSHA1 for the KDF though.) Therefore, + // we did not make this configurable. Note also that choosing an improved + // MAC algorithm here would cause the overall length of the serialized ciphertext + // to be just that much longer, which is probably unacceptable when encrypting + // short strings. + SecretKey sk = new SecretKeySpec(authKey.getEncoded(), "HmacSHA1"); + Mac mac = Mac.getInstance("HmacSHA1"); + mac.init(sk); + if ( requiresIV() ) { + mac.update( getIV() ); + } + byte[] result = mac.doFinal( getRawCipherText() ); + return result; + } catch (NoSuchAlgorithmException e) { + logger.error(Logger.SECURITY_FAILURE, "Cannot compute MAC w/out HmacSHA1.", e); + return null; + } catch (InvalidKeyException e) { + logger.error(Logger.SECURITY_FAILURE, "Cannot comput MAC; invalid 'key' for HmacSHA1.", e); + return null; + } + } + + /** + * Return true if the MAC has already been computed (i.e., not null). + */ + private boolean macComputed() { + return (separate_mac_ != null); + } + + /** + * Return true if we've collected all the required pieces; otherwise false. + */ + private boolean collectedAll() { + EnumSet ctFlags = null; + if ( requiresIV() ) { + ctFlags = allCtFlags; + } else { + EnumSet initVector = EnumSet.of(CipherTextFlags.INITVECTOR); + ctFlags = EnumSet.complementOf(initVector); + } + boolean result = progress.containsAll(ctFlags); + return result; + } + + /** Check if we've collected a specific flag type. + * @param flag The flag type; e.g., {@code CipherTextFlags.INITVECTOR}, etc. + * @return Return true if we've collected a specific flag type; otherwise false. + */ + private boolean isCollected(CipherTextFlags flag) { + return progress.contains(flag); + } + + /** + * Add the flag to the set of what we've already collected. + * @param flag The flag type to be added; e.g., {@code CipherTextFlags.INITVECTOR}. + */ + private void received(CipherTextFlags flag) { + progress.add(flag); + } + + /** + * Add all the flags from the specified set to that we've collected so far. + * @param ctSet A {@code EnumSet} containing all the flags + * we wish to add. + */ + private void received(EnumSet ctSet) { + Iterator it = ctSet.iterator(); + while ( it.hasNext() ) { + received( it.next() ); + } + } + + /** + * Based on the KDF version and the selected MAC algorithm for the KDF PRF, + * calculate the 32-bit quantity representing these. + * @return A 4-byte (octet) quantity representing the KDF version and the + * MAC algorithm used for the KDF's Pseudo-Random Function. + * @see Format of portable serialization of org.owasp.esapi.crypto.CipherText object (pg 2) + */ + public int getKDFInfo() { + final int unusedBit28 = 0x8000000; // 1000000000000000000000000000 + + // kdf version is bits 1-27, bit 28 (reserved) should be 0, and + // bits 29-32 are the MAC algorithm indicating which PRF to use for the KDF. + int kdfVers = this.getKDFVersion(); + if ( ! CryptoHelper.isValidKDFVersion(kdfVers, true, false) ) { + String exm = "Invalid KDF version encountered. Value as" + kdfVers; + throw new EnterpriseSecurityRuntimeException(exm, + "Possible tampering of KDF version #? " + exm); + } + int kdfInfo = kdfVers; + int macAlg = kdfPRFAsInt(); + if ( macAlg < 0 || macAlg > 15 ) { + String exm = "Invalid specifier for MAC algorithm: " + macAlg; + throw new EnterpriseSecurityRuntimeException(exm, + "Possible tampering of macAlg specifier? " + exm + + "; value should be 0 <= macAlg <= 15."); + } + // Make sure bit28 is cleared. (Reserved for future use.) + kdfInfo &= ~unusedBit28; + + // Set MAC algorithm bits in high (MSB) nibble. + kdfInfo |= (macAlg << 28); + + return kdfInfo; + } +} diff --git a/src/main/java/org/owasp/esapi/crypto/CipherTextSerializer.java b/src/main/java/org/owasp/esapi/crypto/CipherTextSerializer.java new file mode 100644 index 000000000..3e155f440 --- /dev/null +++ b/src/main/java/org/owasp/esapi/crypto/CipherTextSerializer.java @@ -0,0 +1,459 @@ +package org.owasp.esapi.crypto; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InvalidClassException; +import java.io.UnsupportedEncodingException; +import java.util.Date; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Logger; +import org.owasp.esapi.util.ByteConversionUtil; +import org.owasp.esapi.errors.EncryptionException; + +/** + * Helper class to assist with programming language and platform independent + * serialization of {@link CipherText} objects. The serialization is done in + * network-byte order which is the same as big-endian byte order. + *

+ * This serialization scheme is documented in + * + * Format of Portable Serialization of org.owasp.esapi.crypto.CipherText Objects. + * Other serialization schemes may be desirable and could be supported (notably, RFC 5083 - Cryptographic + * Message Syntax (CMS) Authenticated-Enveloped-Data Content Type, or CMS' predecessor, + * PKCS#7 (RFC 2315)), but these serialization schemes are by comparison very complicated, + * and do not have extensive support for the various implementation languages which ESAPI + * supports. (Perhaps wishful thinking that other ESAPI implementations such as + * ESAPI for .NET, ESAPI for C, ESAPI for C++, etc. will all support a single, common + * serialization technique, so they could exchange encrypted data.) + * + * @author kevin.w.wall@gmail.com + * @since 2.0 + * + */ +public class CipherTextSerializer { + // This should be *same* version as in CipherText & KeyDerivationFunction as + // these versions all need to work together. Therefore, when one changes one + // one these versions, the other should be reviewed and changed as well to + // accommodate any differences. + // Previous versions: 20110203 - Original version (ESAPI releases 2.0 & 2.0.1) + // 20130830 - Fix to issue #306 (release 2.1.0) + // We check that in an static initialization block below. + public static final int cipherTextSerializerVersion = 20130830; // Current version. Format: YYYYMMDD, max is 99991231. + private static final long serialVersionUID = cipherTextSerializerVersion; + + private static final Logger logger = ESAPI.getLogger("CipherTextSerializer"); + + private CipherText cipherText_ = null; + + // Check if versions of KeyDerivationFunction, CipherText, and + // CipherTextSerializer are all the same. + { + // Ignore error about comparing identical versions and dead code. + // We expect them to be, but the point is to catch us if they aren't. + if ( CipherTextSerializer.cipherTextSerializerVersion != CipherText.cipherTextVersion ) { + throw new ExceptionInInitializerError("Versions of CipherTextSerializer and CipherText are not compatible."); + } + if ( CipherTextSerializer.cipherTextSerializerVersion != KeyDerivationFunction.kdfVersion ) { + throw new ExceptionInInitializerError("Versions of CipherTextSerializer and KeyDerivationFunction are not compatible."); + } + } + + public CipherTextSerializer(CipherText cipherTextObj) { + if ( cipherTextObj == null ) { + throw new IllegalArgumentException("CipherText object must not be null."); + } + cipherText_ = cipherTextObj; + } + + /** + * Given byte array in network byte order (i.e., big-endian order), convert + * it so that a {@code CipherText} can be constructed from it. + * @param cipherTextSerializedBytes A serialized {@code CipherText} object + * with the bytes in network byte order. + * @throws EncryptionException Thrown if a valid {@code CipherText} object + * cannot be reconstructed from the byte array. + */ + public CipherTextSerializer(byte[] cipherTextSerializedBytes) + throws EncryptionException /* DISCUSS: Change exception type?? */ + { + cipherText_ = convertToCipherText(cipherTextSerializedBytes); + } + + /** Return this {@code CipherText} object as a specialized, portable + * serialized byte array. + * @return A serialization of this object. Note that this is not the + * Java serialization. + */ + public byte[] asSerializedByteArray() { + int kdfInfo = cipherText_.getKDFInfo(); + debug("asSerializedByteArray: kdfInfo = " + kdfInfo); + long timestamp = cipherText_.getEncryptionTimestamp(); + String cipherXform = cipherText_.getCipherTransformation(); + if ( cipherText_.getKeySize() >= Short.MAX_VALUE ) { + throw new IllegalArgumentException("Key size is too large. Max is " + Short.MAX_VALUE); + } + short keySize = (short) cipherText_.getKeySize(); + if ( cipherText_.getBlockSize() >= Short.MAX_VALUE ) { + throw new IllegalArgumentException("Block size is too large. Max is " + Short.MAX_VALUE); + } + short blockSize = (short) cipherText_.getBlockSize(); + byte[] iv = cipherText_.getIV(); + if ( iv.length >= Short.MAX_VALUE ) { + throw new IllegalArgumentException("IV size too large. Max is " + Short.MAX_VALUE + " bytes"); + } + short ivLen = (short) iv.length; + byte[] rawCiphertext = cipherText_.getRawCipherText(); + int ciphertextLen = rawCiphertext.length; + // Coverity issue 1352406, GitHub issue # 364 - possible NPE later if assertion disabled. + // Replaced assertion with explicit check. + if ( ciphertextLen < 1 ) { + throw new IllegalArgumentException("Raw ciphertext length must be >= 1 byte."); + } + byte[] mac = cipherText_.getSeparateMAC(); + if ( mac.length >= Short.MAX_VALUE ) { + throw new IllegalArgumentException("MAC length too large. Max is " + Short.MAX_VALUE + " bytes"); + } + short macLen = (short) mac.length; + + byte[] serializedObj = computeSerialization(kdfInfo, + timestamp, + cipherXform, + keySize, + blockSize, + ivLen, + iv, + ciphertextLen, + rawCiphertext, + macLen, + mac + ); + + return serializedObj; + } + + /** + * Return the actual {@code CipherText} object. + * @return The {@code CipherText} object that we are serializing. + */ + public CipherText asCipherText() { + if ( cipherText_ == null ) { + throw new IllegalArgumentException("Program error? CipherText object, cipherText_, must not be null."); + } + return cipherText_; + } + + /** + * Take all the individual elements that make of the serialized ciphertext + * format and put them in order and return them as a byte array. + * @param kdfInfo Info about the KDF... which PRF and the KDF version {@link #asCipherText()}. + * @param timestamp Timestamp when the data was encrypted. Intended to help + * facilitate key change operations and nothing more. If it is meaningless, + * then the expectations are just that the recipient should ignore it. Mostly + * intended when encrypted data is kept long term over a period of many + * key change operations. + * @param cipherXform Details of how the ciphertext was encrypted. The format used + * is the same as used by {@code javax.crypto.Cipher}, namely, + * "cipherAlg/cipherMode/paddingScheme". + * @param keySize The key size used for encrypting. Intended for cipher algorithms + * supporting multiple key sizes such as triple DES (DESede) or + * Blowfish. + * @param blockSize The cipher block size. Intended to support cipher algorithms + * that support variable block sizes, such as Rijndael. + * @param ivLen The length of the IV. + * @param iv The actual IV (initialization vector) bytes. + * @param ciphertextLen The length of the raw ciphertext. + * @param rawCiphertext The actual raw ciphertext itself + * @param macLen The length of the MAC (message authentication code). + * @param mac The MAC itself. + * @return A byte array representing the serialized ciphertext. + */ + private byte[] computeSerialization(int kdfInfo, long timestamp, + String cipherXform, short keySize, + short blockSize, + short ivLen, byte[] iv, + int ciphertextLen, byte[] rawCiphertext, + short macLen, byte[] mac + ) + { + debug("computeSerialization: kdfInfo = " + kdfInfo); + debug("computeSerialization: timestamp = " + new Date(timestamp)); + debug("computeSerialization: cipherXform = " + cipherXform); + debug("computeSerialization: keySize = " + keySize); + debug("computeSerialization: blockSize = " + blockSize); + debug("computeSerialization: ivLen = " + ivLen); + debug("computeSerialization: ciphertextLen = " + ciphertextLen); + debug("computeSerialization: macLen = " + macLen); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + writeInt(baos, kdfInfo); + writeLong(baos, timestamp); + String[] parts = cipherXform.split("/"); + if ( parts.length != 3 ) { + throw new IllegalArgumentException("Program error? Malformed cipher tranformation: " + cipherXform); + } + writeString(baos, cipherXform); // Size of string is prepended to string + writeShort(baos, keySize); + writeShort(baos, blockSize); + writeShort(baos, ivLen); + if ( ivLen > 0 ) baos.write(iv, 0, iv.length); + writeInt(baos, ciphertextLen); + baos.write(rawCiphertext, 0, rawCiphertext.length); + writeShort(baos, macLen); + if ( macLen > 0 ) baos.write(mac, 0, mac.length); + return baos.toByteArray(); + } + + // All strings are written as UTF-8 encoded byte streams with the + // length prepended before it as a short. The prepended length is + // more for the benefit of languages like C, so they can pre-allocate + // char arrays without worrying about buffer overflows. + private void writeString(ByteArrayOutputStream baos, String str) { + byte[] bytes; + try { + if ( str == null || str.length() == 0 ) { + throw new IllegalArgumentException("Program error? writeString: str is null or empty!"); + } + bytes = str.getBytes("UTF8"); + if ( bytes.length >= Short.MAX_VALUE ) { + throw new IllegalArgumentException("Program error? writeString: String exceeds max length of " + + Short.MAX_VALUE + " bytes"); + } + writeShort(baos, (short)bytes.length); + baos.write(bytes, 0, bytes.length); + } catch (UnsupportedEncodingException e) { + // Should never happen. UTF8 is built into the rt.jar. We don't use native encoding as + // a fall-back because that simply is not guaranteed to be portable across Java + // platforms and could cause really bizarre errors way downstream. + logger.error(Logger.EVENT_FAILURE, "Ignoring caught UnsupportedEncodingException " + + "converting string to UTF8 encoding. Results suspect. Corrupt rt.jar????"); + } + } + + private String readString(ByteArrayInputStream bais, short sz) + throws NullPointerException, IOException + { + byte[] bytes = new byte[sz]; + int ret = bais.read(bytes, 0, sz); + if ( ret != sz ) { + throw new IllegalArgumentException("Program error? readString: Expected to read " + + sz + " bytes, but only read " + ret + " bytes"); + } + return new String(bytes, "UTF8"); + } + + private void writeShort(ByteArrayOutputStream baos, short s) { + byte[] shortAsByteArray = ByteConversionUtil.fromShort(s); + if ( shortAsByteArray.length != 2 ) { + throw new IllegalArgumentException("Program error? writeShort: Excepted byte array != 2 bytes."); + } + baos.write(shortAsByteArray, 0, 2); + } + + private short readShort(ByteArrayInputStream bais) + throws NullPointerException, IndexOutOfBoundsException + { + byte[] shortAsByteArray = new byte[2]; + int ret = bais.read(shortAsByteArray, 0, 2); + if ( ret != 2 ) { + throw new IllegalArgumentException("Program error? readShort: Failed to read 2 bytes."); + } + return ByteConversionUtil.toShort(shortAsByteArray); + } + + private void writeInt(ByteArrayOutputStream baos, int i) { + byte[] intAsByteArray = ByteConversionUtil.fromInt(i); + baos.write(intAsByteArray, 0, 4); + } + + private int readInt(ByteArrayInputStream bais) + throws NullPointerException, IndexOutOfBoundsException + { + byte[] intAsByteArray = new byte[4]; + int ret = bais.read(intAsByteArray, 0, 4); + if ( ret != 4 ) { + throw new IllegalArgumentException("Program error? readInt: Failed to read 4 bytes."); + } + return ByteConversionUtil.toInt(intAsByteArray); + } + + private void writeLong(ByteArrayOutputStream baos, long l) { + byte[] longAsByteArray = ByteConversionUtil.fromLong(l); + if ( longAsByteArray.length != 8 ) { + throw new IllegalArgumentException("Program error? writeLong: Expected byte array != 8 bytes."); + } + baos.write(longAsByteArray, 0, 8); + } + + private long readLong(ByteArrayInputStream bais) + throws NullPointerException, IndexOutOfBoundsException + { + byte[] longAsByteArray = new byte[8]; + int ret = bais.read(longAsByteArray, 0, 8); + if ( ret != 8 ) { + throw new IllegalArgumentException("Program error? readLong: Failed to read 8 bytes."); + } + return ByteConversionUtil.toLong(longAsByteArray); + } + + /** Convert the serialized ciphertext byte array to a {@code CipherText} + * object. + * @param cipherTextSerializedBytes The serialized ciphertext as a byte array. + * @return The corresponding {@code CipherText} object. + * @throws EncryptionException Thrown if the byte array data is corrupt or + * there are version mismatches, etc. + */ + private CipherText convertToCipherText(byte[] cipherTextSerializedBytes) + throws EncryptionException + { + try { + if ( cipherTextSerializedBytes == null ) { + throw new IllegalArgumentException("cipherTextSerializedBytes cannot be null."); + } + if ( cipherTextSerializedBytes.length == 0 ) { + throw new IllegalArgumentException("cipherTextSerializedBytes must be > 0 in length."); + } + ByteArrayInputStream bais = new ByteArrayInputStream(cipherTextSerializedBytes); + int kdfInfo = readInt(bais); + debug("kdfInfo: " + kdfInfo); + int kdfPrf = (kdfInfo >>> 28); + debug("kdfPrf: " + kdfPrf); + if ( kdfPrf < 0 || kdfPrf > 16 ) { + throw new IllegalArgumentException("Program error? convertToCipherText: kdPrf is " + kdfPrf + + ". Must be between 0 and 15 inclusive"); + } + int kdfVers = ( kdfInfo & 0x07ffffff); + + // First do a quick sanity check on the argument. Previously this was an assertion. + if ( ! CryptoHelper.isValidKDFVersion(kdfVers, false, false) ) { + // TODO: Clean up. Use StringBuilder. Good enough for now. + String logMsg = "KDF version read from serialized ciphertext (" + kdfVers + ") is out of range. " + + "Valid range for KDF version is [" + KeyDerivationFunction.originalVersion + ", " + + "99991231]."; + // This should never happen under actual circumstances (barring programming errors; but we've + // tested the code, right?), so it is likely an attempted attack. Thus don't get the originator + // of the suspect ciphertext too much info. They ought to know what they sent anyhow. + throw new EncryptionException("Version info from serialized ciphertext not in valid range.", + "Likely tampering with KDF version on serialized ciphertext." + logMsg); + } + + debug("convertToCipherText: kdfPrf = " + kdfPrf + ", kdfVers = " + kdfVers); + if ( ! versionIsCompatible( kdfVers) ) { + throw new EncryptionException("This version of ESAPI is not compatible with the version of ESAPI that encrypted your data.", + "KDF version " + kdfVers + " from serialized ciphertext not compatibile with current KDF version of " + + KeyDerivationFunction.kdfVersion); + } + long timestamp = readLong(bais); + debug("convertToCipherText: timestamp = " + new Date(timestamp)); + short strSize = readShort(bais); + debug("convertToCipherText: length of cipherXform = " + strSize); + String cipherXform = readString(bais, strSize); + debug("convertToCipherText: cipherXform = " + cipherXform); + String[] parts = cipherXform.split("/"); + if ( parts.length != 3 ) { + throw new IllegalArgumentException("Program error? Malformed cipher transformation. Expecting 3 parts to cipher transformation, " + + "alg/mode/padding, but found " + parts.length + " parts (" + cipherXform + ")."); + } + String cipherMode = parts[1]; + if ( ! CryptoHelper.isAllowedCipherMode(cipherMode) ) { + String msg = "Cipher mode " + cipherMode + " is not an allowed cipher mode"; + throw new EncryptionException(msg, msg); + } + short keySize = readShort(bais); + debug("convertToCipherText: keySize = " + keySize); + short blockSize = readShort(bais); + debug("convertToCipherText: blockSize = " + blockSize); + short ivLen = readShort(bais); + debug("convertToCipherText: ivLen = " + ivLen); + byte[] iv = null; + if ( ivLen > 0 ) { + iv = new byte[ivLen]; + bais.read(iv, 0, iv.length); + } + int ciphertextLen = readInt(bais); + debug("convertToCipherText: ciphertextLen = " + ciphertextLen); + if ( ciphertextLen <= 0 ) { + throw new IllegalArgumentException("convertToCipherText: Invalid cipher text length; must be > 0."); + } + byte[] rawCiphertext = new byte[ciphertextLen]; + bais.read(rawCiphertext, 0, rawCiphertext.length); + short macLen = readShort(bais); + debug("convertToCipherText: macLen = " + macLen); + byte[] mac = null; + if ( macLen > 0 ) { + mac = new byte[macLen]; + bais.read(mac, 0, mac.length); + } + + CipherSpec cipherSpec = new CipherSpec(cipherXform, keySize); + cipherSpec.setBlockSize(blockSize); + cipherSpec.setIV(iv); + debug("convertToCipherText: CipherSpec: " + cipherSpec); + CipherText ct = new CipherText(cipherSpec); + if ( ! (ivLen > 0 && ct.requiresIV()) ) { + throw new EncryptionException("convertToCipherText: Mismatch between IV length and cipher mode.", + "Possible tampering of serialized ciphertext?"); + } + ct.setCiphertext(rawCiphertext); + // Set this *AFTER* setting raw ciphertext because setCiphertext() + // method also sets encryption time. + ct.setEncryptionTimestamp(timestamp); + if ( macLen > 0 ) { + ct.storeSeparateMAC(mac); + } + // Fixed in ESAPI crypto version 20130839. Previously is didn't really matter + // because there was only one version (20110203) and it defaulted to that + // version, which was the current version. But we don't want that as now there + // are two versions, and we could be decrypting data encrypted using the previous + // version. + ct.setKDF_PRF(kdfPrf); + ct.setKDFVersion(kdfVers); + return ct; + } catch(EncryptionException ex) { + throw new EncryptionException("Cannot deserialize byte array into CipherText object", + "Cannot deserialize byte array into CipherText object", + ex); + } catch (IOException e) { + throw new EncryptionException("Cannot deserialize byte array into CipherText object", + "Cannot deserialize byte array into CipherText object", e); + } + } + + /** Check to see if we can support the KSF version that was extracted from + * the serialized ciphertext. In particular, we assume that if we have a + * newer version of KDF than we can support it as we assume that we have + * built in backward compatibility. + * + * At this point (ESAPI 2.1.0, KDF version 20130830), all we need to check + * if the version is either the current version or the previous version as + * both versions work the same. This checking may get more complicated in + * the future. + * + * @param readKdfVers The version information extracted from the serialized + * ciphertext. + */ + private static boolean versionIsCompatible(int readKdfVers) { + if ( readKdfVers <= 0 ) { + throw new IllegalArgumentException("Extracted KDF version is <= 0. Must be integer >= 1."); + } + + switch ( readKdfVers ) { + case KeyDerivationFunction.originalVersion: // First version + return true; + // Add new versions here; hard coding is OK... + // case YYYYMMDD: + // return true; + case KeyDerivationFunction.kdfVersion: // Current version + return true; + default: + return false; + } + } + + private void debug(String msg) { + if ( logger.isDebugEnabled() ) { + logger.debug(Logger.EVENT_SUCCESS, msg); + } + } +} diff --git a/src/main/java/org/owasp/esapi/crypto/CryptoDiscoverer.java b/src/main/java/org/owasp/esapi/crypto/CryptoDiscoverer.java new file mode 100644 index 000000000..53ab1c7c0 --- /dev/null +++ b/src/main/java/org/owasp/esapi/crypto/CryptoDiscoverer.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) 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 Chris Schmidt (chris.schmidt@owasp.org) + * @created 2010 + */ +package org.owasp.esapi.crypto; + +import java.security.Provider; +import java.security.Security; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Pattern; + +public class CryptoDiscoverer { + private static String EOL = System.getProperty("line.separator", "\n"); + + public static void main(String... args) { + String provider = ".*"; + String algorithm = ".*"; + + if ( args.length > 0 ) { + if ( args[0].equals( "--help" ) ) { + usage(); + System.exit(0); + } + + List argList = Arrays.asList( args ); + + int argIdx = argList.indexOf("--provider"); + if ( argIdx > -1 && argList.size() > (argIdx + 1) ) { + provider = argList.get(argIdx+1); + } + + argIdx = argList.indexOf("--algorithm"); + if ( argIdx > -1 && argList.size() > (argIdx + 1) ) { + algorithm = argList.get(argIdx+1); + } + } + + Pattern providerPattern = Pattern.compile(provider); + Pattern algorithmPattern = Pattern.compile(algorithm); + + System.out.println("Searching for Providers Matching: " + provider ); + System.out.println("Searching for Algorithms Matching: " + algorithm ); + System.out.println(); + + for (Provider p : Security.getProviders()) { + if ( providerPattern.matcher(p.getName()).matches()) { + System.out.println("Provider: " + p.getName()); + for (Provider.Service service : p.getServices()) { + if ( algorithmPattern.matcher(service.getAlgorithm()).matches()) { + System.out.println("\tAlgorithm: " + service.getAlgorithm()); + } + } + } + } + } + + private static void usage() { + System.out.println("CryptoDiscoverer - Discover or Query for available Crypto Providers and Algorithms"); + System.out.println(EOL + "\t--help\t\t\t\t\tShows this message" + EOL + + "\t--provider \t\tSearch for particular Provider" + EOL + + "\t--algorithm \t\tSearch for a particular Algorithm" + EOL + EOL); + } +} diff --git a/src/main/java/org/owasp/esapi/crypto/CryptoHelper.java b/src/main/java/org/owasp/esapi/crypto/CryptoHelper.java new file mode 100644 index 000000000..2254837ce --- /dev/null +++ b/src/main/java/org/owasp/esapi/crypto/CryptoHelper.java @@ -0,0 +1,414 @@ +/* + * 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) 2009 - The OWASP Foundation + */ +package org.owasp.esapi.crypto; + +import java.io.UnsupportedEncodingException; +import java.security.InvalidKeyException; +import java.security.InvalidParameterException; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import java.util.List; + +import javax.crypto.KeyGenerator; +import javax.crypto.Mac; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Logger; +import org.owasp.esapi.errors.EncryptionException; + +/** + * Class to provide some convenience methods for encryption, decryption, etc. + *

+ * All the cryptographic operations use the default cryptographic properties; + * e.g., default cipher transformation, default key size, default IV type (where + * applicable), etc. + * + * @author kevin.w.wall@gmail.com + * @since 2.0 + */ +public class CryptoHelper { + + private static final Logger logger = ESAPI.getLogger("CryptoHelper"); + + // TODO: Also consider supplying implementation of RFC 2898 / PKCS#5 PBKDF2 + // in this file as well??? Maybe save for ESAPI 2.1 or 3.0. + /** + * Generate a random secret key appropriate to the specified cipher algorithm + * and key size. + * @param alg The cipher algorithm or cipher transformation. (If the latter is + * passed, the cipher algorithm is determined from it.) Cannot be + * null or empty. + * @param keySize The key size, in bits. + * @return A random {@code SecretKey} is returned. + * @throws EncryptionException Thrown if cannot create secret key conforming to + * requested algorithm with requested size. Typically, this is caused by + * specifying an unavailable algorithm or invalid key size. + */ + public static SecretKey generateSecretKey(String alg, int keySize) + throws EncryptionException + { + if ( alg == null || alg.equals("") ) { + throw new IllegalArgumentException("Algorithm must not be null or empty."); // Avoid later possibly ambiguous NPE. + } + if ( keySize <= 0 ) { + throw new IllegalArgumentException("Key size must be positive."); // Usually should be an even multiple of 8, but not strictly required by alg. + } + // Don't use CipherSpec here to get algorithm as this may cause assertion + // to fail (when enabled) if only algorithm name is passed to us. + String[] cipherSpec = alg.split("/"); + String cipherAlg = cipherSpec[0]; + try { + // Special case for things like PBEWithMD5AndDES or PBEWithSHA1AndDESede. + // In such cases, the key generator should only request an instance of "PBE". + if ( cipherAlg.toUpperCase().startsWith("PBEWITH") ) { + cipherAlg = "PBE"; + } + KeyGenerator kgen = + KeyGenerator.getInstance( cipherAlg ); + kgen.init(keySize); + return kgen.generateKey(); + } catch (NoSuchAlgorithmException e) { + throw new EncryptionException("Failed to generate random secret key", + "Invalid algorithm. Failed to generate secret key for " + alg + " with size of " + keySize + " bits.", e); + } catch (InvalidParameterException e) { + throw new EncryptionException("Failed to generate random secret key - invalid key size specified.", + "Invalid key size. Failed to generate secret key for " + alg + " with size of " + keySize + " bits.", e); + } + } + + /** + * The method is ESAPI's Key Derivation Function (KDF) that computes a + * derived key from the {@code keyDerivationKey} for either + * encryption / decryption or for authentication. + *

+ * CAUTION: If this algorithm for computing derived keys from the + * key derivation key is ever changed, we risk breaking backward compatibility of being + * able to decrypt data previously encrypted with earlier / different versions + * of this method. Therefore, do not change this unless you are 100% certain that + * what you are doing will NOT change either of the derived keys for + * ANY "key derivation key" AT ALL!!! + *

+ * NOTE: This method is generally not intended to be called separately. + * It is used by ESAPI's reference crypto implementation class {@code JavaEncryptor} + * and might be useful for someone implementing their own replacement class, but + * generally it is not something that is useful to application client code. + * + * @param keyDerivationKey A key used as an input to a key derivation function + * to derive other keys. This is the key that generally + * is created using some key generation mechanism such as + * {@link #generateSecretKey(String, int)}. The + * "input" key from which the other keys are derived. + * The derived key will have the same algorithm type + * as this key. + * @param keySize The cipher's key size (in bits) for the {@code keyDerivationKey}. + * Must have a minimum size of 56 bits and be an integral multiple of 8-bits. + * Note: The derived key will have the same size as this. + * @param purpose The purpose for the derived key. Must be either the + * string "encryption" or "authenticity". Use "encryption" for + * creating a derived key to use for confidentiality, and "authenticity" + * for a derived key to use with a MAC to ensure message authenticity. + * @return The derived {@code SecretKey} to be used according + * to the specified purpose. Note that this serves the same purpose + * as "label" in section 5.1 of NIST SP 800-108. + * @throws NoSuchAlgorithmException The {@code keyDerivationKey} has an unsupported + * encryption algorithm or no current JCE provider supports + * "HmacSHA1". + * @throws EncryptionException If "UTF-8" is not supported as an encoding, then + * this is thrown with the original {@code UnsupportedEncodingException} + * as the cause. (NOTE: This should never happen as "UTF-8" is supposed to + * be a common encoding supported by all Java implementations. Support + * for it is usually in rt.jar.) This exception is also thrown if the + * requested {@code keySize} parameter exceeds the length of the number of + * bytes provided in the {@code keyDerivationKey} parameter. + * @throws InvalidKeyException Likely indicates a coding error. Should not happen. + * @throws EncryptionException Throw for some precondition violations. + * @deprecated Use same method in {@code KeyDerivationFunction} instead. This method will be removed as of + * ESAPI release 2.3 so if you are using this, please CHANGE YOUR CODE. Note that the replacement + * is not a static method, so create your own wrapper if you wish, but this will soon disappear. + */ + @Deprecated + public static SecretKey computeDerivedKey(SecretKey keyDerivationKey, int keySize, String purpose) + throws NoSuchAlgorithmException, InvalidKeyException, EncryptionException + { + // Fingers cross; maybe this will help. + logger.warning(Logger.SECURITY_AUDIT, + "Your code is using the deprecated CryptoHelper.computeDerivedKey() method which will be removed next release"); + + if ( keyDerivationKey == null ) { + throw new IllegalArgumentException("Key derivation key cannot be null."); + } + // We would choose a larger minimum key size, but we want to be + // able to accept DES for legacy encryption needs. + if ( keySize < 56 ) { + throw new IllegalArgumentException("Key has size of " + keySize + ", which is less than minimum of 56-bits."); + } + if ( (keySize % 8) != 0 ) { + throw new IllegalArgumentException("Key size (" + keySize + ") must be a even multiple of 8-bits."); + } + if ( purpose == null ) { + throw new IllegalArgumentException("'purpose' may not be null."); + } + if ( ! ( purpose.equals("encryption") || purpose.equals("authenticity") ) ) { + throw new IllegalArgumentException("Purpose must be \"encryption\" or \"authenticity\"."); + } + + // DISCUSS: Should we use HmacSHA1 (what we were using) or the HMAC defined by + // Encryptor.KDF.PRF instead? Either way, this is not compatible with + // previous ESAPI versions. JavaEncryptor doesn't use this any longer. + // ANSWER: This is deprecated and will be removed in 2.3.0.0, so it really matter + // that much. However, Since the property Encryptor.KDF.PRF is (and has + // been) "HMacSHA256". changing this could unintentionally break code. + KeyDerivationFunction kdf = new KeyDerivationFunction( + KeyDerivationFunction.PRF_ALGORITHMS.HmacSHA1); + return kdf.computeDerivedKey(keyDerivationKey, keySize, purpose); + } + + /** + * Return true if specified cipher mode is one of those specified in the + * {@code ESAPI.properties} file that supports both confidentiality + * and authenticity (i.e., a "combined cipher mode" as NIST refers + * to it). + * @param cipherMode The specified cipher mode to be used for the encryption + * or decryption operation. + * @return true if the specified cipher mode is in the comma-separated list + * of cipher modes supporting both confidentiality and authenticity; + * otherwise false. + * @see org.owasp.esapi.SecurityConfiguration#getCombinedCipherModes() + */ + public static boolean isCombinedCipherMode(String cipherMode) + { + if ( cipherMode == null ) { + throw new IllegalArgumentException("Cipher mode may not be null"); + } + if ( cipherMode.equals("") ) { + throw new IllegalArgumentException("Cipher mode may not be empty string"); + } + List combinedCipherModes = + ESAPI.securityConfiguration().getCombinedCipherModes(); + return combinedCipherModes.contains( cipherMode ); + } + + /** + * Return true if specified cipher mode is one that may be used for + * encryption / decryption operations via {@link org.owasp.esapi.Encryptor}. + * @param cipherMode The specified cipher mode to be used for the encryption + * or decryption operation. + * @return true if the specified cipher mode is in the comma-separated list + * of cipher modes supporting both confidentiality and authenticity; + * otherwise false. + * @see #isCombinedCipherMode(String) + * @see org.owasp.esapi.SecurityConfiguration#getCombinedCipherModes() + * @see org.owasp.esapi.SecurityConfiguration#getAdditionalAllowedCipherModes() + */ + public static boolean isAllowedCipherMode(String cipherMode) + { + if ( isCombinedCipherMode(cipherMode) ) { + return true; + } + List extraCipherModes = + ESAPI.securityConfiguration().getAdditionalAllowedCipherModes(); + return extraCipherModes.contains( cipherMode ); + } + + /** + * Check to see if a Message Authentication Code (MAC) is required + * for a given {@code CipherText} object and the current ESAPI.property + * settings. A MAC is considered "required" if the specified + * {@code CipherText} was not encrypted by one of the preferred + * "combined" cipher modes (e.g., CCM or GCM) and the setting of the + * current ESAPI properties for the property + * {@code Encryptor.CipherText.useMAC} is set to {@code true}. (Normally, + * the setting for {@code Encryptor.CipherText.useMAC} should be set to + * {@code true} unless FIPS 140-2 compliance is required. See + * + * User Guide for Symmetric Encryption in ESAPI 2.0 and the section + * on using ESAPI with FIPS for further details. + * + * @param ct The specified {@code CipherText} object to check to see if + * it requires a MAC. + * @return True if a MAC is required, false if it is not required. + */ + public static boolean isMACRequired(CipherText ct) { + boolean preferredCipherMode = + CryptoHelper.isCombinedCipherMode( ct.getCipherMode() ); + boolean wantsMAC = ESAPI.securityConfiguration().useMACforCipherText(); + + // The preferred "combined" cipher modes such as CCM, GCM, etc. do + // not require a MAC as a MAC would be superfluous and just require + // additional computing time. + return ( !preferredCipherMode && wantsMAC ); + } + + /** + * If a Message Authentication Code (MAC) is required for the specified + * {@code CipherText} object, then attempt to validate the MAC that + * should be embedded within the {@code CipherText} object by using a + * derived key based on the specified {@code SecretKey}. + * + * @param sk The {@code SecretKey} used to derive a key to check + * the authenticity via the MAC. + * @param ct The {@code CipherText} that we are checking for a + * valid MAC. + * + * @return True is returned if a MAC is required and it is valid as + * verified using a key derived from the specified + * {@code SecretKey} or a MAC is not required. False is returned + * otherwise. + */ + public static boolean isCipherTextMACvalid(SecretKey sk, CipherText ct) + { + if ( CryptoHelper.isMACRequired( ct ) ) { + try { + KeyDerivationFunction kdf = new KeyDerivationFunction( ct.getKDF_PRF() ); + SecretKey authKey = kdf.computeDerivedKey(sk, ct.getKeySize(), "authenticity"); + boolean validMAC = ct.validateMAC( authKey ); + return validMAC; + } catch (Exception ex) { + // Error on side of security. If this fails and can't verify MAC + // assume it is invalid. Note that CipherText.toString() does not + // print the actual ciphertext. + logger.warning(Logger.SECURITY_FAILURE, "Unable to validate MAC for ciphertext " + ct, ex); + return false; + } + } + return true; + } + + /** + * Overwrite a byte array with a specified byte. This is frequently done + * to a plaintext byte array so the sensitive data is not lying around + * exposed in memory. + * @param bytes The byte array to be overwritten. + * @param x The byte array {@code bytes} is overwritten with this byte. + */ + public static void overwrite(byte[] bytes, byte x) + { + Arrays.fill(bytes, x); + } + + /** + * Overwrite a byte array with the byte containing '*'. That is, call + *

+     *         overwrite(bytes, (byte)'*');
+     * 
+ * @param bytes The byte array to be overwritten. + */ + public static void overwrite(byte[] bytes) + { + overwrite(bytes, (byte)'*'); + } + + // These provide for a bit more type safety when copying bytes around. + /** + * Same as {@code System.arraycopy(src, 0, dest, 0, length)}. + * + * @param src the source array. + * @param dest the destination array. + * @param length the number of array elements to be copied. + * @exception IndexOutOfBoundsException if copying would cause + * access of data outside array bounds. + * @exception NullPointerException if either src or + * dest is null. + */ + public static void copyByteArray(final byte[] src, byte[] dest, int length) + { + System.arraycopy(src, 0, dest, 0, length); + } + + /** + * Same as {@code copyByteArray(src, dest, src.length)}. + * @param src the source array. + * @param dest the destination array. + * @exception IndexOutOfBoundsException if copying would cause + * access of data outside array bounds. + * @exception NullPointerException if either src or + * dest is null. + */ + public static void copyByteArray(final byte[] src, byte[] dest) + { + copyByteArray(src, dest, src.length); + } + + /** + * A "safe" array comparison that is not vulnerable to side-channel + * "timing attacks". All comparisons of non-null, equal length bytes should + * take same amount of time. We use this for cryptographic comparisons. + * + * @param b1 A byte array to compare. + * @param b2 A second byte array to compare. + * @return {@code true} if both byte arrays are null or if both byte + * arrays are identical or have the same value; otherwise + * {@code false} is returned. + * @deprecated Use java.security.MessageDigest#isEqual(byte[], byte[]) instead. + */ + @Deprecated + public static boolean arrayCompare(byte[] b1, byte[] b2) { + // Note: See GitHub issue #246 and #554. + // If we make Java 8 the minimal ESAPI baseline before we remove this + // method, we can at least remove these next 6 lines. (Issue 554.) + if ( b1 == null && b2 == null ) { // Must test this first! + return true; // Prevent NPE; compatibility with Java 8 and later. + } + if ( b1 == null || b2 == null ) { + return false; // Prevent NPE; compatibility with Java 8 and later. + } + return java.security.MessageDigest.isEqual(b1, b2); + } + + /** + * Is this particular KDF version number one that is sane? For that, we + * just make sure it is inbounds of the valid range which is: + *
+     *     [20110203, 99991231]
+     * 
+ * @param kdfVers KDF version # that we are checking. Generally this is + * extracted from the serialized {@code CipherText}. + * @param restrictToCurrent If this is set, we do an additional check + * to see if the KDF version is a later version than the + * one that this current ESAPI version supports. + * @param throwIfError Instead of returning {@code false} in the case of + * an error, throw an {@code IllegalArgumentException} + * @return True if in range, false otherwise (except if {@code throwIfError} + * is true.} + */ + public static boolean isValidKDFVersion(int kdfVers, boolean restrictToCurrent, + boolean throwIfError) + throws IllegalArgumentException + { + boolean ret = true; + + if ( kdfVers < KeyDerivationFunction.originalVersion || kdfVers > 99991231 ) { + ret = false; + } else if ( restrictToCurrent ) { + ret = ( kdfVers <= KeyDerivationFunction.kdfVersion ); + } + if ( ret ) { + return ret; // True + } else { // False, so throw or not. + logger.warning(Logger.SECURITY_FAILURE, "Possible data tampering. Encountered invalid KDF version #. " + + ( throwIfError ? "Throwing IllegalArgumentException" : "" )); + if ( throwIfError ) { + throw new IllegalArgumentException("Version (" + kdfVers + ") invalid. " + + "Must be date in format of YYYYMMDD between " + KeyDerivationFunction.originalVersion + "and 99991231."); + } + } + return false; + } + + /** + * Prevent public, no-argument CTOR from being auto-generated. Public CTOR + * is not needed as all methods are static. + */ + private CryptoHelper() { + ; // Prevent default CTOR from being auto-created. + } +} diff --git a/src/main/java/org/owasp/esapi/crypto/CryptoToken.java b/src/main/java/org/owasp/esapi/crypto/CryptoToken.java new file mode 100644 index 000000000..c6171b75a --- /dev/null +++ b/src/main/java/org/owasp/esapi/crypto/CryptoToken.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 © 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. + * + * @created 2010 + */ +package org.owasp.esapi.crypto; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.Map.Entry; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Encryptor; +import org.owasp.esapi.Logger; +import org.owasp.esapi.errors.EncodingException; +import org.owasp.esapi.errors.EncryptionException; +import org.owasp.esapi.errors.EncryptionRuntimeException; +import org.owasp.esapi.errors.ConfigurationException; +import org.owasp.esapi.errors.ValidationException; + +///// IMPORTANT NOTE: Never print / log attribute *values* as they +///// may be sensitive. Also, do not log the CryptoToken +///// itself, because even it is encrypted, the token itself +///// is often used as an authentication token. + +/** + * Compute a cryptographically secure, encrypted token containing + * optional name/value pairs. The cryptographic token is computed + * like this: + *
+ *     username;expiration_time;[<attr1>;<attr2>;...;<attrN>;]
+ * 
+ * where + * username is a user account name. Defaults to <anonymous> if + * not set and it is always converted to lower case as per the rules of the + * default locale. (Note this lower case conversion is consistent with the + * default reference implementation of ESAPI's {@code User} interface.) + *
+ * expiration_time is time (in milliseconds) after which the encrypted + * token is considered invalid (i.e., expired). The time is stored as + * milliseconds since midnight, January 1, 1970 UTC, and optional attributes + *
+ *   <attr1>;<attr2>;...<attrN>; + *
+ * are optional semicolon (';') separated name/value pairs, where each + * name/value pair has the form: + *
+ *         name=[value]        (value may be empty, but not null)
+ * 
+ * The attribute value may contain any value. However, values containing + * either '=' or ';' will be quoted using '\'. Likewise, values containing '\' + * will also be quoted using '\'. Hence, if original name/value pair were + * name=ab=xy\; * this would be represented as name=ab\=xy\\\;. + * To ensure things are "safe" (from a security perspective), attribute + * names must conform to the Java regular expression + *
+ *          [A-Za-z0-9_\.-]+
+ * 
+ * The attribute value on the other hand, may be any valid string. (That + * is, the value is not checked, so beware! When rendering these values, output + * encoding may be required to prevent XSS. Use ESAPI's {@code Encoder} for that. + *

+ * This entire semicolon-separated string is then encrypted via one of the + * {@code Encryptor.encrypt()} methods and then base64-encoded, serialized + * IV + ciphertext + MAC representation as determined by + * {@code CipherTextasPortableSerializedByteArray()} is used as the + * resulting cryptographic token. + *

+ * The attributes are sorted by attribute name and the attribute names + * must be unique. There are some restrictions on the attribute names. + * (See the {@link #setAttribute(String, String)} method for details.) + * + * WARNING: You should never print / log attribute values as + * they may be sensitive. Also, do not log the {@code CryptoToken} + * itself, because even though it is encrypted, the token itself is + * often used as an authentication token. + * + * @author kevin.w.wall@gmail.com + * @since 2.0 + */ +public class CryptoToken { + /** Represents an anonymous user. */ + public static final String ANONYMOUS_USER = ""; + + // Default expiration time + private static final long DEFAULT_EXP_TIME = 5 * 60 * 1000; // 5 min == 300 milliseconds + private static final String DELIM = ";"; // field delimiter + private static final char DELIM_CHAR = ';'; // field delim as a char + private static final char QUOTE_CHAR = '\\'; // char used to quote delimiters, '=' and itself. + + // OPEN ISSUE: Should we make these 2 regex's properties in ESAPI.properties??? + private static final String ATTR_NAME_REGEX = "[A-Za-z0-9_.-]+"; // One or more alphanumeric, underscore, periods, or hyphens. + private static final String USERNAME_REGEX = "[a-z][a-z0-9_.@-]*"; + + private static Logger logger = ESAPI.getLogger("CryptoToken"); + + private String username = ANONYMOUS_USER; // Default user name if not set. Always lower case. + private long expirationTime = 0L; + // This probably needed be sorted. A HashMap would do as well. + // But this might make debugging a bit easier, so why not? + private TreeMap attributes = new TreeMap(); + private transient SecretKey secretKey = null; + private Pattern attrNameRegex = Pattern.compile(ATTR_NAME_REGEX); + private Pattern userNameRegex = Pattern.compile(USERNAME_REGEX); + + /** + * Create a cryptographic token using default secret key from the + * ESAPI.properties property Encryptor.MasterKey. + */ + public CryptoToken() { + secretKey = getDefaultSecretKey( + ESAPI.securityConfiguration().getEncryptionAlgorithm() + ); + long now = System.currentTimeMillis(); + expirationTime = now + DEFAULT_EXP_TIME; + } + + // Create using specified SecretKey + /** + * Create a cryptographic token using specified {@code SecretKey}. + * + * @param skey The specified {@code SecretKey} to use to encrypt the token. + */ + public CryptoToken(SecretKey skey) { + if ( skey == null ) { + throw new IllegalArgumentException("SecretKey may not be null."); + } + secretKey = skey; + long now = System.currentTimeMillis(); + expirationTime = now + DEFAULT_EXP_TIME; + } + + /** + * Create using previously encrypted token encrypted with default secret + * key from ESAPI.properties. + * @param token A previously encrypted token returned by one of the + * {@code getToken()} or {@code updateToken()} methods. The + * token must have been previously encrypted using the + * using default secret key from the ESAPI.properties + * property Encryptor.MasterKey. + * @throws EncryptionException Thrown if they are any problems while decrypting + * the token using the default secret key from + * ESAPI.properties or if the decrypted + * token is not properly formatted. + */ + public CryptoToken(String token) throws EncryptionException { + secretKey = getDefaultSecretKey( + ESAPI.securityConfiguration().getEncryptionAlgorithm() + ); + try { + decryptToken(secretKey, token); + } catch (EncodingException e) { + throw new EncryptionException("Decryption of token failed. Token improperly encoded or encrypted with different key.", + "Can't decrypt token because not correctly encoded or encrypted with different key.", e); + } + if ( username == null ) { + throw new IllegalArgumentException("Programming error or malformed token: Decrypted token found username null."); + } + if ( expirationTime <= 0 ) { + throw new IllegalArgumentException("Programming error or malformed token: Decrypted token found expirationTime <= 0."); + } + } + + /** + * Create cryptographic token using previously encrypted token that was + * encrypted with specified secret key. + * + * @param token A previously encrypted token returned by one of the + * {@code getToken()} or {@code updateToken()} methods. + * @throws EncryptionException Thrown if they are any problems while decrypting + * the token using the default secret key from + * ESAPI.properties or if the decrypted + * token is not properly formatted. + */ + // token is a previously encrypted token (i.e., CryptoToken.getToken()) + // with different SecretKey other than the one in ESAPI.properties + public CryptoToken(SecretKey skey, String token) throws EncryptionException { + if ( skey == null ) { + throw new IllegalArgumentException("SecretKey may not be null."); + } + if ( token == null ) { + throw new IllegalArgumentException("Token may not be null"); + } + secretKey = skey; + try { + decryptToken(secretKey, token); + } catch (EncodingException e) { + throw new EncryptionException("Decryption of token failed. Token improperly encoded.", + "Can't decrypt token because not correctly encoded.", e); + } + if ( username == null ) { + String exm = "Programming error???: Decrypted token found username null."; + throw new EncryptionException(exm, exm); + } + if ( expirationTime <= 0 ) { + String exm = "Programming error???: Decrypted token found expirationTime <= 0."; + throw new EncryptionException(exm, exm); + } + } + + /** + * Retrieve the user account name associated with this {@code CryptoToken} + * object. + * @return The user account name. The string represented by + * {@link #ANONYMOUS_USER} is returned if + * {@link #setUserAccountName(String)} was never called. + */ + public String getUserAccountName() { + return ( (username != null) ? username : ANONYMOUS_USER ); + } + + /** + * Set the user account name associated with this cryptographic token + * object. The user account name is converted to lower case. + * @param userAccountName The user account name. + * @throws ValidationException Thrown if user account name is not valid, i.e., + * if it doesn't conform to the regular expression + * given by "[a-z][a-z0-9_.@-]*". (Note that the + * parameter {@code userAccountName} is first converted + * to lower case before checked against the regular + * expression.) + */ + public void setUserAccountName(String userAccountName) throws ValidationException { + if ( userAccountName == null ) { + throw new IllegalArgumentException("User account name may not be null."); + } + + // Converting to lower case first allows a simpler regex. + String userAcct = userAccountName.toLowerCase(); + + // Check to make sure that attribute name is valid as per our regex. + Matcher userNameChecker = userNameRegex.matcher(userAcct); + if ( userNameChecker.matches() ) { + username = userAcct; + } else { + throw new ValidationException("Invalid user account name encountered.", + "User account name " + userAccountName + + " does not match regex " + + USERNAME_REGEX + " after conversion to lowercase."); + } + } + + /** Check if token has expired yet. + * @return True if token has expired; false otherwise. + */ + public boolean isExpired() { + return System.currentTimeMillis() > expirationTime; + } + + /** + * Set expiration time to expire in 'interval' seconds (NOT milliseconds). + * @param intervalSecs Number of seconds in the future from current date/time + * to set expiration. Must be positive. + */ + public void setExpiration(int intervalSecs) throws IllegalArgumentException + { + int intervalMillis = intervalSecs * 1000; // Need to convert secs to millisec. + + // Don't want to use assertion here, because if they are disabled, + // this would result in setting the expiration time prior to the + // current time, hence it would already be expired. + if ( intervalMillis <= 0) { + throw new IllegalArgumentException("intervalSecs argument, converted to millisecs, must be > 0."); + } + // Check for arithmetic overflow here. In reality, this condition + // should never happen, but we want to avoid it--even theoretically-- + // since otherwise, it could have security implications. + long now = System.currentTimeMillis(); + preAdd(now, intervalMillis); + expirationTime = now + intervalMillis; + } + + /** + * Set expiration time for a specific date/time. + * @param expirationDate The date/time at which the token will fail. Must + * be after the current date/time. + * @throws IllegalArgumentException Thrown if the parameter is null. + */ + public void setExpiration(Date expirationDate) throws IllegalArgumentException + { + if ( expirationDate == null ) { + throw new IllegalArgumentException("expirationDate may not be null."); + } + long curTime = System.currentTimeMillis(); + long expTime = expirationDate.getTime(); + if ( expTime <= curTime ) { + throw new IllegalArgumentException("Expiration date must be after current date/time."); + } + expirationTime = expTime; + } + + /** + * Return the expiration time in milliseconds since epoch time (midnight, + * January 1, 1970 UTC). + * @return The current expiration time. + */ + public long getExpiration() { + // Assertion here is safe as it is just a sanity check and this check is + // make elsewhere. Plus this is a getter, not a setting, so if it's + // messed up, it happened somewhere else. + assert expirationTime > 0L : "Programming error: Expiration time <= 0"; + return expirationTime; + } + + /** + * Return the expiration time as a {@code Date}. + * @return The {@code Date} object representing the expiration time. + */ + public Date getExpirationDate() { + return new Date( getExpiration() ); + } + + /** + * Set a name/value pair as an attribute. + * @param name The attribute name + * @param value The attribute value + * @throws ValidationException Thrown if the attribute name is not properly + * formed. That is, the attribute name does not + * match the regular expression "[A-Za-z0-9_.-]+". + */ + public void setAttribute(String name, String value) throws ValidationException { + if ( name == null || name.length() == 0 ) { + throw new ValidationException("Null or empty attribute NAME encountered", + "Attribute NAMES may not be null or empty string."); + } + if ( value == null ) { + throw new ValidationException("Null attribute VALUE encountered for attr name " + name, + "Attribute VALUE may not be null; attr name: " + name); + } + // NOTE: OTOH, it *is* VALID if the _value_ is empty! Null values cause too much trouble + // to make it worth the effort of getting it to work consistently. + + // Check to make sure that attribute name is valid as per our regex. + Matcher attrNameChecker = attrNameRegex.matcher(name); + if ( attrNameChecker.matches() ) { + attributes.put(name, value); + } else { + throw new ValidationException("Invalid attribute name encountered.", + "Attribute name " + name + " does not match regex " + + ATTR_NAME_REGEX); + } + } + + /** + * Add the specified collection of attributes to the current attributes. + * If there are duplicate attributes specified, they will replace any + * existing ones. + * + * @param attrs Name/value pairs of attributes to add or replace the existing + * attributes. Map must be non-null, but may be empty. + * @throws ValidationException Thrown if one of the keys in the specified + * parameter {@code attrs} is not a valid name. + * That is, all attribute names must match the regular + * expression ""[A-Za-z0-9_.-]+". + * @see #setAttribute(String, String) + */ + public void addAttributes(final Map attrs) throws ValidationException { + if ( attrs == null ) { + throw new IllegalArgumentException("Attribute map may not be null."); + } + Set< Entry > keyValueSet = attrs.entrySet(); + Iterator> it = keyValueSet.iterator(); + while( it.hasNext() ) { + Map.Entry entry = it.next(); + String key = entry.getKey(); + String value = entry.getValue(); + setAttribute(key, value); + } + return; + } + + /** + * Retrieve the attribute with the specified name. + * @param name The attribute name. + * @return The value associated with the attribute name. If attribute is not + * set, then {@code null} is returned. + */ + public String getAttribute(String name) { + return attributes.get(name); + } + + /** + * Retrieve a {@code Map} that is a clone of all the attributes. A copy + * is returned so that the attributes in {@code CrytpToken} are unaffected + * by alterations made the returned {@code Map}. (Otherwise, multi-threaded code + * could get trick. + * + * @return A {@code Map} of all the attributes. + * @see #getAttribute(String) + */ + @SuppressWarnings("unchecked") + public Map getAttributes() { + // Unfortunately, this requires a cast, which requires us to supress warnings. + return (Map) attributes.clone(); + } + + /** + * Removes all the attributes (if any) associated with this token. Note + * that this does not clear / reset the user account name or expiration time. + */ + public void clearAttributes() { + attributes.clear(); + } + + /** + * Return the new encrypted token as a base64-encoded string, encrypted with + * the specified {@code SecretKey} which may be a different key than what the + * token was originally encrypted with. E.g., + *

+     *   Alice:
+     *      SecretKey aliceSecretKey = ...; // Shared with Bob
+     *      CryptoToken cryptoToken = new CryptoToken(skey1);
+     *      cryptoToken.setUserAccountName("kwwall");
+     *      cryptoToken.setAttribute("role", "admin");
+     *      cryptoToken.setAttribute("state", "Ohio");
+     *      String token = cryptoToken.getToken(); // Encrypted with skey1
+     *      // send token to Bob ...
+     *  --------------------------------------------------------------------
+     *  Bob:
+     *      ...
+     *      SecretKey aliceSecretKey = ...  // Shared with Alice
+     *      SecretKey bobSecretKey = ...;   // Shared with Carol
+     *      CryptoToken cryptoToken = new CryptoToken(aliceSecretKey, tokenFromAlice);
+     *
+     *      // Re-encrypt for Carol using my (Bob's) key...
+     *      String tokenForCarol = cryptoToken.getToken(bobSecretKey);
+     *      // send tokenForCarol to Carol ...
+     *      // use token ourselves
+     *  --------------------------------------------------------------------
+     *  Carol:
+     *      ...
+     *      SecretKey bobSecretKey = ...;   // Shared with Bob.
+     *      CryptoToken cryptoToken = new CryptoToken(bobSecretKey, tokenFromBob);
+     *      if ( ! cryptoToken.isExpired() ) {
+     *          String userName = cryptoToken.getUserAccountName();
+     *          String roleName = cryptoToken.getAttribute("role");
+     *          if ( roleName != null && roleName.equalsIgnoreCase("admin") ) {
+     *              // grant admin access...
+     *              ...
+     *          }
+     *      }
+     *      ...
+     * 
+ * @param skey The specified key to (re)encrypt the token. + * @return The newly encrypted token. + */ + public String getToken(SecretKey skey) throws EncryptionException { + return createEncryptedToken(skey); + } + + /** + * Update the (current) expiration time by adding the specified number of + * seconds to it and then re-encrypting with the current {@code SecretKey} + * that was used to construct this object. + * + * @param additionalSecs The additional number of seconds to add to the + * current expiration time. This number must be + * >= 0 or otherwise an {@code IllegalArgumentException} + * is thrown. + * @return The re-encrypted token with the updated expiration time is returned. + * @throws IllegalArgumentException Thrown if parameter {@code additionalSecs} + * is less than 0. + * @throws EncryptionException Thrown if the encryption fails. + * @throws ValidationException Thrown if the token will have already expired + * even after adding the specified number of + * additional seconds. + * @throws ArithmeticException If additional seconds is large enough such + * that it would cause an arithmetic overflow + * with a long (the current expiration time) + * when added to the {@code additionalSecs} + * parameter. + */ + public String updateToken(int additionalSecs) throws EncryptionException, ValidationException { + if ( additionalSecs < 0) { + throw new IllegalArgumentException("additionalSecs argument must be >= 0."); + } + + // Avoid integer overflow. This could happen if one first calls + // setExpiration(Date) with a date far into the future. We want + // to avoid overflows as they might lead to security vulnerabilities. + long curExpTime = getExpiration(); + preAdd(curExpTime, additionalSecs * 1000); + // Note: Can't use setExpiration(int) here was this needs a + // 'long'. Could convert to Date first, and use + // setExpiration(Date) but that hardly seems worth the trouble. + expirationTime = curExpTime + (additionalSecs * 1000); + + if ( isExpired() ) { + // Too bad there is no ProcrastinationException ;-) + expirationTime = curExpTime; // Restore the original value (which still may + // be expired. + throw new ValidationException("Token timed out.", + "Cryptographic token not increased to sufficient value to prevent timeout."); + + } + // Don't change anything else (user acct name, attributes, skey, etc.) + return getToken(); + } + + /** + * Return the new encrypted token as a base64-encoded string, encrypted with + * the specified {@code SecretKey} with which this object was constructed. + * + * @return The newly encrypted token. + * @see #getToken(SecretKey) + */ + public String getToken() throws EncryptionException { + return createEncryptedToken(secretKey); + } + + // Create the actual encrypted token based on the specified SecretKey. + // This method will ensure that the decrypted token always ends with an + // unquoted delimiter. + private String createEncryptedToken(SecretKey skey) throws EncryptionException { + StringBuilder sb = new StringBuilder( getUserAccountName() + DELIM); + // CHECKME: Should we check here to see if token has already expired + // and refuse to encrypt it (by throwing exception) if it has??? + // If so, then updateToken() should also be revisited. + sb.append( getExpiration() ).append( DELIM ); + sb.append( getQuotedAttributes() ); + + Encryptor encryptor = ESAPI.encryptor(); + CipherText ct = encryptor.encrypt(skey, new PlainText( sb.toString() ) ); + String b64 = + ESAPI.encoder().encodeForBase64(ct.asPortableSerializedByteArray(), + false); + return b64; + } + + // Return a string of all the attributes, properly quoted. This is used in + // creating the encrypted token. Note that this method ensures that the + // quoted attribute string always ends with an (quoted) delimiter. + private String getQuotedAttributes() { + StringBuilder sb = new StringBuilder(); + Set< Entry > keyValueSet = attributes.entrySet(); + Iterator> it = keyValueSet.iterator(); + while( it.hasNext() ) { + Map.Entry entry = it.next(); + String key = entry.getKey(); + String value = entry.getValue(); + // Because attribute values may be confidential, we don't want to log them! + logger.debug(Logger.EVENT_UNSPECIFIED, " " + key + " -> "); + sb.append(key + "=" + quoteAttributeValue( value ) + DELIM); + } + return sb.toString(); + } + + // Do NOT define a toString() method as there may be sensitive + // information contained in the attribute names. If we absolutely + // need this, then only return the username and expiration time, and + // _maybe_ the attribute names, but not there values. And obviously, + // we NEVER want to include the SecretKey should we decide to do this. + /* + * public String toString() { return null; } + */ + + + // Quote any special characters in value. + private static String quoteAttributeValue(String value) { + if ( value == null ) { + String exm = "Programming error???: Value should not be null."; // Empty string is OK. + throw new EncryptionRuntimeException(exm, exm); + } + StringBuilder sb = new StringBuilder(); + char[] charArray = value.toCharArray(); + for( int i = 0; i < charArray.length; i++ ) { + char c = charArray[i]; + if ( c == QUOTE_CHAR || c == '=' || c == DELIM_CHAR ) { + sb.append(QUOTE_CHAR).append(c); + } else { + sb.append(c); + } + } + return sb.toString(); + } + + // Parse the possibly quoted value and return the unquoted value. + private static String parseQuotedValue(String quotedValue) { + StringBuilder sb = new StringBuilder(); + char[] charArray = quotedValue.toCharArray(); + for( int i = 0; i < charArray.length; i++ ) { + char c = charArray[i]; + if ( c == QUOTE_CHAR ) { + i++; // Skip past quote character. + sb.append( charArray[i] ); + } else { + sb.append(c); + } + } + return sb.toString(); + } + + /* + * Decrypt the encrypted token and parse it into the individual components. + * The string should always end with a semicolon (;) even when there are + * no attributes set. + *

+ * Example of how quoted string might look: + *

+     *                            v              v  v            v     v
+     *  kwwall;1291183520293;abc=x\=yx;xyz=;efg=a\;a\;;bbb=quotes\\tuff\;;
+              |             |         |    |          |                  |
+     *
+     * 
+ */ + private void decryptToken(SecretKey skey, String b64token) throws EncryptionException, EncodingException { + byte[] token = null; + try { + token = ESAPI.encoder().decodeFromBase64(b64token); + } catch (IOException e) { + // Ideally, we'd like to be able to include the actual (munged) token itself. + // It's encrypted, but could be arbitrarily long, especially since it is not valid + // encoding. In theory, it may help debugging as sometimes it may be a simple + // case like someone failing to apply some other type of encoding + // consistently (e.g., URL encoding), in which case logging this should + // make this pretty obvious once a few of these are logged. + // + // OTOH, since tokens may be used as authentication tokens (see + // "WARNING" in the class Javadoc) some insider could intentionally botch + // a token (e.g., just remove the base64 padding characters) just to + // get an otherwise valid token logged somewhere they can access it. + // Therefore, I have decided NOT to include in in the logMessage + // part of the exception. + // + // Note that prior to ESAPI 2.2.0.0, the token _was_ logged, but has + // now been corrected. + // + throw new EncodingException("Invalid base64 encoding.", + "Invalid base64 encoding for token [REDACTED]"); + } + CipherText ct = CipherText.fromPortableSerializedBytes(token); + Encryptor encryptor = ESAPI.encryptor(); + PlainText pt = encryptor.decrypt(skey, ct); + String str = pt.toString(); + if ( ! str.endsWith(DELIM) ) { + String exm = "Programming error???: Expecting decrypted token to end with delim char, " + DELIM_CHAR; + throw new EncryptionException(exm, exm); + } + char[] charArray = str.toCharArray(); + int prevPos = -1; // Position of previous unquoted delimiter. + int fieldNo = 0; + ArrayList fields = new ArrayList(); + int lastPos = charArray.length; + for ( int curPos = 0; curPos < lastPos; curPos++ ) { + boolean quoted = false; + char curChar = charArray[curPos]; + if ( curChar == QUOTE_CHAR ) { + // Found a case where we have quoted character. We need to skip + // over this and set the current character to the next character. + curPos++; + if ( curChar != lastPos ) { + curChar = charArray[ curPos + 1 ]; + quoted = true; + } else { + // Last position will always be a delimiter character that + // should be treated as unquoted. + curChar = DELIM_CHAR; + } + } + if ( curChar == DELIM_CHAR && !quoted ) { + // We found an actual (unquoted) field delimiter. + String record = str.substring(prevPos + 1, curPos); + fields.add( record ); + fieldNo++; + prevPos = curPos; + } + } + + Object[] objArray = fields.toArray(); + if ( fieldNo != objArray.length ) { + String exm = "Programming error???: Mismatch of delimited field count."; + throw new EncryptionException(exm, exm); + } + logger.debug(Logger.EVENT_UNSPECIFIED, "Found " + objArray.length + " fields."); + if ( objArray.length < 2 ) { + String exm = "Missing mandatory fields from decrypted token (username &/or expiration time)."; + throw new EncryptionException(exm, exm); + } + username = ((String)(objArray[0])).toLowerCase(); + String expTime = (String)objArray[1]; + expirationTime = Long.parseLong(expTime); + + for( int i = 2; i < objArray.length; i++ ) { + String nvpair = (String)objArray[i]; + int equalsAt = nvpair.indexOf("="); + if ( equalsAt == -1 ) { + throw new EncryptionException("Invalid attribute encountered in decrypted token.", + "Malformed attribute name/value pair (" + nvpair + ") found in decrypted token."); + } + String name = nvpair.substring(0, equalsAt); + String quotedValue = nvpair.substring(equalsAt + 1); + String value = parseQuotedValue( quotedValue ); + // Because attribute values may be confidential, we don't want to log them! + logger.debug(Logger.EVENT_UNSPECIFIED, "Attribute[" + i + "]: name=" + name + ", value="); + + // Check to make sure that attribute name is valid as per our regex. + Matcher attrNameChecker = attrNameRegex.matcher(name); + if ( attrNameChecker.matches() ) { + attributes.put(name, value); + } else { + throw new EncryptionException("Invalid attribute name encountered in decrypted token.", + "Invalid attribute name encountered in decrypted token; " + + "attribute name " + name + " does not match regex " + + ATTR_NAME_REGEX); + } + attributes.put(name, value); + } + return; + } + + private SecretKey getDefaultSecretKey(String encryptAlgorithm) { + if ( encryptAlgorithm == null ) { + throw new IllegalArgumentException("Encryption algorithm cannot be null"); + } + byte[] skey = ESAPI.securityConfiguration().getMasterKey(); + if ( skey == null ) { + throw new IllegalArgumentException("Can't obtain master key, Encryptor.MasterKey"); + } + if ( skey.length < 7 ) { + throw new ConfigurationException( + "Encryptor.MasterKey must be at least 7 bytes. " + + "Length is: " + skey.length + " bytes."); + } + // Set up secretKeySpec for use for symmetric encryption and decryption, + // and set up the public/private keys for asymmetric encryption / + // decryption. + return new SecretKeySpec(skey, encryptAlgorithm ); + } + + // Check precondition to see if addition of two operands will result in + // arithmetic overflow. Note that the operands are of two different + // integral types. I.e., check to see if: + // long result = leftLongValue + rightIntValue + // would cause arithmetic overflow. + // Note: We know that as we use it here, leftLongValue will always be > 0, + // so arithmetic underflow should never be possible, but we check for + // it anyhow. + // Package level access to allow this to be used by other classes in this package. + static final void preAdd(long leftLongValue, int rightIntValue) throws ArithmeticException { + if ( rightIntValue > 0 && ( (leftLongValue + rightIntValue) < leftLongValue) ) { + throw new ArithmeticException("Arithmetic overflow for addition."); + } + if ( rightIntValue < 0 && ( (leftLongValue + rightIntValue) > leftLongValue) ) { + throw new ArithmeticException("Arithmetic underflow for addition."); + } + } + +} diff --git a/src/main/java/org/owasp/esapi/crypto/KeyDerivationFunction.java b/src/main/java/org/owasp/esapi/crypto/KeyDerivationFunction.java new file mode 100644 index 000000000..02f925bfb --- /dev/null +++ b/src/main/java/org/owasp/esapi/crypto/KeyDerivationFunction.java @@ -0,0 +1,531 @@ +/* + * 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 © 2011 - The OWASP Foundation + */ +package org.owasp.esapi.crypto; + +import java.io.UnsupportedEncodingException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; + +import javax.crypto.Mac; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Logger; +import org.owasp.esapi.errors.ConfigurationException; +import org.owasp.esapi.errors.EncryptionException; +import static org.owasp.esapi.PropNames.KDF_PRF_ALG; +import org.owasp.esapi.util.ByteConversionUtil; + +/** + * This class implements a Key Derivation Function (KDF) and supporting methods. + * A KDF is a function with which an input key (called the Key Derivation Key, + * or KDK) and other input data are used to securely generate (i.e., derive) + * keying material that can be employed by cryptographic algorithms. + *

+ * Acknowledgments: + * ESAPI's KDF is patterned after suggestions first made by cryptographer + * Dr. David A. Wagner and later extended to follow KDF in counter mode + * as specified by section 5.1 of NIST SP 800-108. Jeffrey Walton and the NSA + * also made valuable suggestions regarding the modeling of the method, + * {@link #computeDerivedKey(SecretKey, int, String)}. + * + * @author kevin.w.wall@gmail.com + * @since 2.0 + */ +public class KeyDerivationFunction { + /** + * Used to support backward compatibility. {@code kdfVersion} is used as the + * version for the serialized encrypted ciphertext on all the "encrypt" + * operations. This static field should be the same as + * {@link CipherText#cipherTextVersion} and + * {@link CipherTextSerializer#cipherTextSerializerVersion} to make sure + * that these classes are all kept in-sync in order to support backward + * compatibility of previously encrypted data. + *

+     * Previous versions:    20110203 - Original version (ESAPI releases 2.0 & 2.0.1)
+     *                        20130830 - Fix to issue #306 (release 2.1.0)
+     * 
+ * @see CipherTextSerializer#asSerializedByteArray() + * @see CipherText#asPortableSerializedByteArray() + * @see CipherText#fromPortableSerializedBytes(byte[]) + */ + public static final int originalVersion = 20110203; // First version. Do not change. EVER! + public static final int kdfVersion = 20130830; // Current version. Format: YYYYMMDD, max is 99991231. + private static final long serialVersionUID = kdfVersion; // Format: YYYYMMDD + + // Pseudo-random function algorithms suitable for NIST KDF in counter mode. + // Note that HmacMD5 is intentionally omitted here!!! + public enum PRF_ALGORITHMS { + // SHA-1, 160-bits + HmacSHA1(0, 160, "HmacSHA1"), + // SHA-2 candidates, 256-, 384-, and 512-bits + HmacSHA256(1, 256, "HmacSHA256"), + HmacSHA384(2, 384, "HmacSHA384"), + HmacSHA512(3, 512, "HmacSHA512"); + // Reserved for SHA-3 winner, 224-, 256-, 384-, and 512-bits + // Names not yet known. Will use standard JCE alg names here. + // + // E.g., might be something like + // HmacSHA3_224(4, 224, "HmacSHA3-224"), + // HmacSHA3_256(5, 256, "HmacSHA3-256"), + // HmacSHA3_384(6, 384, "HmacSHA3-385"), + // HmacSHA3_512(7, 512, "HmacSHA3-512"); + // Reserved for future use -- values 8 through 15 + // Most likely these might be some other strong contenders that + // were are based on HMACs from the NIST SHA-3 finalists. + + private final byte value; // Value stored in serialized encrypted data to represent PRF + private final short bits; + private final String algName; + + PRF_ALGORITHMS(int value, int bits, String algName) { + this.value = (byte) value; + this.bits = (short) bits; + this.algName = algName; + } + + public byte getValue() { return value; } + public short getBits() { return bits; } + public String getAlgName() { return algName; } + } + + private static final Logger logger = ESAPI.getLogger("KeyDerivationFunction"); + + private String prfAlg_ = null; + private int version_ = kdfVersion; + private String context_ = ""; + + // Check if versions of KeyDerivationFunction, CipherText, and + // CipherTextSerializer are all the same. + { + // Ignore error about comparing identical versions and dead code. + // We expect them to be, but the point is to catch us if they aren't. + if ( CipherTextSerializer.cipherTextSerializerVersion != CipherText.cipherTextVersion ) { + throw new ExceptionInInitializerError("Versions of CipherTextSerializer and CipherText are not compatible."); + } + if ( CipherTextSerializer.cipherTextSerializerVersion != KeyDerivationFunction.kdfVersion ) { + throw new ExceptionInInitializerError("Versions of CipherTextSerializer and KeyDerivationFunction are not compatible."); + } + } + + /** + * Construct a {@code KeyDerivationFunction}. + * @param prfAlg Specifies a supported algorithm. + */ + public KeyDerivationFunction(KeyDerivationFunction.PRF_ALGORITHMS prfAlg) { + this.prfAlg_ = prfAlg.getAlgName(); + } + + /** + * Construct a {@code KeyDerivationFunction} based on the + * ESAPI.property property, {@code Encryptor.KDF.PRF}. + */ + public KeyDerivationFunction() { + String prfName = ESAPI.securityConfiguration().getKDFPseudoRandomFunction(); + if ( ! KeyDerivationFunction.isValidPRF(prfName) ) { + throw new ConfigurationException("Algorithm name " + prfName + + " not a valid algorithm name for property " + + KDF_PRF_ALG); + } + prfAlg_ = prfName; + } + + /** + * Return the name of the algorithm for the Pseudo Random Function (PRF) + * that is being used. + * @return The PRF algorithm name. + */ + public String getPRFAlgName() { + return prfAlg_; + } + + /** + * Package level method for use by {@code CipherText} class to get default + * + */ + static int getDefaultPRFSelection() { + String prfName = ESAPI.securityConfiguration().getKDFPseudoRandomFunction(); + for (PRF_ALGORITHMS prf : PRF_ALGORITHMS.values()) { + if ( prf.getAlgName().equals(prfName) ) { + return prf.getValue(); + } + } + throw new ConfigurationException("Algorithm name " + prfName + + " not a valid algorithm name for property " + KDF_PRF_ALG); + } + + /** + * Set version so backward compatibility can be supported. Used to set the + * version to some previous version so that previously encrypted data can + * be decrypted. + * @param version Date as a integer, in format of YYYYMMDD. Maximum + * version date is 99991231 (December 31, 9999). + * @throws IllegalArgumentException If {@code version} is not within + * the valid range of [20110203, 99991231]. + */ + public void setVersion(int version) throws IllegalArgumentException { + CryptoHelper.isValidKDFVersion(version, false, true); + this.version_ = version; + } + + /** + * Return the version used for backward compatibility. + * @return The KDF version #, in format YYYYMMDD, used for supporting + * backward compatibility. + */ + public int getVersion() { + return version_; + } + + + // TODO: IMPORTANT NOTE: In a future release (hopefully starting in 2.3), + // we will be using the 'context' to mix in some additional things. At a + // minimum, we will be using the KDF version (version_) so that downgrade version + // attacks are not possible. Other candidates are the cipher xform and + // the timestamp. + /** + * Set the 'context' as specified by NIST Special Publication 800-108. NIST + * defines 'context' as "A binary string containing the information related + * to the derived keying material. It may include identities of parties who + * are deriving and/or using the derived keying material and, optionally, a + * once known by the parties who derive the keys." NIST SP 800-108 seems to + * imply that while 'context' is recommended, that it is optional. In section + * 7.6 of NIST 800-108, NIST uses "SHOULD" rather than "MUST": + *
+ * "Derived keying material should be bound to all relying + * entities and other information to identify the derived + * keying material. This is called context binding. + * In particular, the identity (or identifier, as the term + * is defined in [NIST SP 800-56A , sic] and [NIST SP + * 800-56B , sic]) of each entity that will access (meaning + * derive, hold, use, and/or distribute) any segment of + * the keying material should be included in the Context + * string input to the KDF, provided that this information + * is known by each entity who derives the keying material." + *
+ * The ISO/IEC's KDF2 uses a similar construction for their KDF and there + * 'context' data is not specified at all. Therefore, ESAPI 2.0's + * reference implementation, {@code JavaEncryptor}, chooses not to use + * 'context' at all. + * + * @param context Optional binary string containing information related to + * the derived keying material. By default (if this method + * is never called), the empty string is used. May have any + * value but {@code null}. + */ + public void setContext(String context) { + if ( context == null ) { + throw new IllegalArgumentException("Context may not be null."); + } + context_ = context; + } + + /** + * Return the optional 'context' that typically contains information + * related to the keying material, such as the identities of the message + * sender and recipient. + * @see #setContext(String) + * @return The 'context' is returned. + */ + public String getContext() { + return context_; + } + + /** + * The method is ESAPI's Key Derivation Function (KDF) that computes a + * derived key from the {@code keyDerivationKey} for either + * encryption / decryption or for authentication. + *

+ * CAUTION: If this algorithm for computing derived keys from the + * key derivation key is ever changed, we risk breaking backward compatibility of being + * able to decrypt data previously encrypted with earlier / different versions + * of this method. Therefore, do not change this unless you are 100% certain that + * what you are doing will NOT change either of the derived keys for + * ANY "key derivation key" AT ALL!!! + *

+ * NOTE: This method is generally not intended to be called separately. + * It is used by ESAPI's reference crypto implementation class {@code JavaEncryptor} + * and might be useful for someone implementing their own replacement class, but + * generally it is not something that is useful to application client code. + * + * @param keyDerivationKey A key used as an input to a key derivation function + * to derive other keys. This is the key that generally + * is created using some key generation mechanism such as + * {@link CryptoHelper#generateSecretKey(String, int)}. The + * "input" key from which the other keys are derived. + * The derived key will have the same algorithm type + * as this key. This KDK cannot be null. + * @param keySize The cipher's key size (in bits) for the {@code keyDerivationKey}. + * Must have a minimum size of 56 bits and be an integral multiple of 8-bits. + * Note: The derived key will have the same size as this. + * @param purpose The purpose for the derived key. IMPORTANT: For the ESAPI reference implementation, + * {@code JavaEncryptor}, this must be either the string "encryption" or + * "authenticity", where "encryption" is used for creating a derived key to use + * for confidentiality, and "authenticity" is used for creating a derived key to + * use with a MAC to ensure message authenticity. However, since parameter serves + * the same purpose as the "Label" in section 5.1 of NIST SP 800-108, it really can + * be set to anything other than {@code null} or an empty string when called outside + * of ESAPI's {@code JavaEncryptor} reference implementation (but you must consistent). + * @return The derived {@code SecretKey} to be used according + * to the specified purpose. + * @throws NoSuchAlgorithmException The {@code keyDerivationKey} has an unsupported + * encryption algorithm or no current JCE provider supports requested + * Hmac algorithrm used for the PRF for key generation. + * @throws EncryptionException If "UTF-8" is not supported as an encoding, then + * this is thrown with the original {@code UnsupportedEncodingException} + * as the cause. (NOTE: This should never happen as "UTF-8" is supposed to + * be a common encoding supported by all Java implementations. Support + * for it is usually in rt.jar.) This exception is also thrown if the + * requested {@code keySize} parameter exceeds the length of the number of + * bytes provded in the {@code keyDerivationKey} parameter. + * @throws InvalidKeyException Likely indicates a coding error. Should not happen. + * @throws EncryptionException Throw for some precondition violations. + */ + public SecretKey computeDerivedKey(SecretKey keyDerivationKey, int keySize, String purpose) + throws NoSuchAlgorithmException, InvalidKeyException, EncryptionException + { + // Acknowledgments: David Wagner first suggested this approach, I (Kevin Wall) + // stumbled upon NIST SP 800-108 and used it as a basis to + // extend it. Later it was changed that conforms more closely + // to section 5.1 of NIST SP 800-108 based on feedback from + // Jeffrey Walton. + // + + // These checks used to be assertions prior to ESAPI 2.1.0.1 + if ( keyDerivationKey == null ) { + throw new IllegalArgumentException("Key derivation key cannot be null."); + } + // We would choose a larger minimum key size, but we want to allow + // this KDF to be able to accept DES for legacy encryption needs. (Note that + // elsewhere there are checks that disallow *encryption* for key size + // less than Encryptor.EncryptionKeyLength bits, so if they want + // ESAPI to encrypt stuff for DES, they would have to set that up to + // be 56 bits. But I can't think of any valid symmetric encryption + // algorithm whose key size is less than 56 bits that we would ever + // want to allow. + if ( keySize < 56 ) { + throw new IllegalArgumentException("Key has size of " + keySize + + ", which is less than minimum of 56-bits."); + } + if ( (keySize % 8) != 0 ) { + throw new IllegalArgumentException("Key size (" + keySize + + ") must be a even multiple of 8-bits."); + } + if ( purpose == null || "".equals(purpose) ) { + throw new IllegalArgumentException("Purpose may not be null or empty."); + } + + // + // No longer, since we no longer wish to restrict this to use only by JavaEncryptor, so + // we no longer test for this. For details, see the javadoc for '@param purpose', above. + // + /* + * + * if ( ! ( purpose.equals("encryption") || purpose.equals("authenticity") ) ) { + * throw new IllegalArgumentException("Purpose must be \"encryption\" or \"authenticity\"."); + * } + * + */ + + int providedKeyLen = 8 * keyDerivationKey.getEncoded().length; + // assert providedKeyLen >= 56 : "Coding error? Length of keyDerivationKey < 56 bits!"; // Ugh. DES compatible. + + if ( providedKeyLen < keySize ) { + throw new EncryptionException("KeyDerivationFunction.computeDerivedKey() not intended for key stretching: " + + "provided key too short (" + providedKeyLen + " bits) to provide " + keySize + " bits.", + "Key stretching not supported: Provided key, keyDerivationKey, has insufficient entropy (" + + providedKeyLen + " bits) to generate key of requested size of " + keySize + " bits."); + } + + keySize = calcKeySize( keySize ); // Safely convert from bits to a whole # of bytes. + byte[] derivedKey = new byte[ keySize ]; + byte[] label; // Same purpose as NIST SP 800-108's "label" in section 5.1. + byte[] context; // See setContext() for details. + try { + label = purpose.getBytes("UTF-8"); + context = context_.getBytes("UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new EncryptionException("Encryption failure (internal encoding error: UTF-8)", + "UTF-8 encoding is NOT supported as a standard byte encoding: " + e.getMessage(), e); + } + + // Note that keyDerivationKey is going to be some SecretKey like an AES or + // DESede key, but not an HmacSHA1 key. That means it is not likely + // going to be 20 bytes but something different. Experiments show + // that doesn't really matter though as the SecretKeySpec CTOR on + // the following line still returns the appropriate sized key for + // HmacSHA1. So, if keyDerivationKey was originally (say) a 56-bit + // DES key, then there is apparently some key-stretching going on here + // under the hood to create 'sk' so that it is 20 bytes. I cannot vouch + // for how secure this key-stretching is. Worse, it might not be specified + // as to *how* it is done and left to each JCE provider. + SecretKey sk = new SecretKeySpec(keyDerivationKey.getEncoded(), prfAlg_ ); + Mac mac = null; + + try { + mac = Mac.getInstance( prfAlg_ ); + mac.init(sk); + } catch( InvalidKeyException ex ) { + logger.error(Logger.SECURITY_FAILURE, + "Created " + prfAlg_ + " Mac but SecretKey sk has alg " + + sk.getAlgorithm(), ex); + throw ex; + } + + // Repeatedly call of PRF Hmac until we've collected enough bits + // for the derived key. The first time through, we calculate the HmacSHA1 + // on the "purpose" string, but subsequent calculations are performed + // on the previous result. + int ctr = 1; // Iteration counter for NIST 800-108 + int totalCopied = 0; + int destPos = 0; + int len = 0; + byte[] tmpKey = null; // Do not declare inside do-while loop!!! + do { + // + // This is to make our KDF more along the line of NIST's. + // NIST's Special Publication 800-108 performs the following in + // the iterative loop of Section 5.1: + // n := number of blocks required to fulfill request + // for i = 1 to n, do + // K(i) := PRF(KDK, [i]2 || Label || 0x00 || Context || [L]2) + // result(i) := result(i-1) || K(i) + // end + // where '||' is represents bit string concatenation, and PRF is + // an NIST approved pseudo-random function (such as an HMAC), + // KDK is the key derivation key, [i]2 is the big-endian binary + // representation of the iteration, and [L]2 is the bits + // requested by the caller, and 0x00 represents a null byte + // used as a separation indicator. However, other sections of this + // document (Section 7.6) implies that Context is to be an + // optional field (based on NIST's use of the word SHOULD + // rather than MUST) + // + mac.update( ByteConversionUtil.fromInt( ctr++ ) ); + mac.update(label); + mac.update((byte) '\0'); + mac.update(context); // This is problematic for us. See Jeff Walton's + // analysis of ESAPI 2.0's KDF for details. + // Maybe for 2.1, we'll see; 2.0 too close to GA. + + // According to the Javadoc for Mac.doFinal(byte[]), + // "A call to this method resets this Mac object to the state it was + // in when previously initialized via a call to init(Key) or + // init(Key, AlgorithmParameterSpec). That is, the object is reset + // and available to generate another MAC from the same key, if + // desired, via new calls to update and doFinal." Therefore, we do + // not do an explicit reset(). + tmpKey = mac.doFinal( ByteConversionUtil.fromInt( keySize ) ); + + if ( tmpKey.length >= keySize ) { + len = keySize; + } else { + len = Math.min(tmpKey.length, keySize - totalCopied); + } + System.arraycopy(tmpKey, 0, derivedKey, destPos, len); + label = tmpKey; + totalCopied += tmpKey.length; + destPos += len; + } while( totalCopied < keySize ); + + // Don't leave remnants of the partial key in memory. (Note: we could + // not do this if tmpKey were declared in the do-while loop. + // Of course, in reality, trying to stomp these bits out is probably not + // realistic because the JIT is likely toing to be smart enough to + // optimze this loop away. We probably could try to outsmart it, by + // (say) writing out the overwritten bits to /dev/null, but then even + // then we'd still probably have to overwrite with random bits rather + // than all null chars. How much is enough? Who knows? But it does point + // to a serious limitation in Java and many other languages that one + // cannot arbitrarily disable the optimizer either at compile time or + // run time because of security reasons. Sigh. At least we've tried. + for ( int i = 0; i < tmpKey.length; i++ ) { + tmpKey[i] = '\0'; + } + tmpKey = null; // Make it immediately eligible for GC. + + // Convert it back into a SecretKey of the appropriate type. + return new SecretKeySpec(derivedKey, keyDerivationKey.getAlgorithm()); + } + + /** + * Check if specified algorithm name is a valid PRF that can be used. + * @param prfAlgName Name of the PRF algorithm; e.g., "HmacSHA1", "HmacSHA384", etc. + * @return True if {@code prfAlgName} is supported, otherwise false. + */ + public static boolean isValidPRF(String prfAlgName) { + for (PRF_ALGORITHMS prf : PRF_ALGORITHMS.values()) { + if ( prf.getAlgName().equals(prfAlgName) ) { + return true; + } + } + return false; + } + + public static PRF_ALGORITHMS convertNameToPRF(String prfAlgName) { + for (PRF_ALGORITHMS prf : PRF_ALGORITHMS.values()) { + if ( prf.getAlgName().equals(prfAlgName) ) { + return prf; + } + } + throw new IllegalArgumentException("Algorithm name " + prfAlgName + + " not a valid PRF algorithm name for the ESAPI KDF."); + } + + public static PRF_ALGORITHMS convertIntToPRF(int selection) { + for (PRF_ALGORITHMS prf : PRF_ALGORITHMS.values()) { + if ( prf.getValue() == selection ) { + return prf; + } + } + throw new IllegalArgumentException("No KDF PRF algorithm found for value name " + selection); + } + + /** + * Calculate the size of a key. The key size is given in bits, but we + * can only allocate them by octets (i.e., bytes), so make sure we + * round up to the next whole number of octets to have room for all + * the bits. For example, a key size of 9 bits would require 2 octets + * to store it. + * + * @param ks The key size, in bits. + * @return The key size, in octets, large enough to accommodate + * {@code ks} bits. + */ + private static int calcKeySize(int ks) { + if ( ks <= 0 ) { + throw new IllegalArgumentException("Key size must be > 0 bits."); + } + int numBytes = 0; + int n = ks/8; + int rem = ks % 8; + if ( rem == 0 ) { + numBytes = n; + } else { + numBytes = n + 1; + } + return numBytes; + } + + /** + * Print list of ESAPI supported pseudo-random functions for KDF and + * KDF version information. + * + * @param args Required, but not used. + */ + public static final void main(String args[]) { + System.out.println("Supported pseudo-random functions for KDF (version: " + kdfVersion + ")"); + System.out.println("Enum Name\tAlgorithm\t# bits"); + for (PRF_ALGORITHMS prf : PRF_ALGORITHMS.values()) { + System.out.println(prf + "\t" + prf.getAlgName() + "\t" + prf.getBits()); + } + } +} diff --git a/src/main/java/org/owasp/esapi/crypto/PlainText.java b/src/main/java/org/owasp/esapi/crypto/PlainText.java new file mode 100644 index 000000000..4866b8048 --- /dev/null +++ b/src/main/java/org/owasp/esapi/crypto/PlainText.java @@ -0,0 +1,161 @@ +package org.owasp.esapi.crypto; + +import java.io.Serializable; +import java.io.UnsupportedEncodingException; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Logger; + +/** + * A class representing plaintext (versus ciphertext) as related to + * cryptographic systems. This class embodies UTF-8 byte-encoding to + * translate between byte arrays and {@code String}s. Once constructed, this + * object is immutable. + *

+ * Note: Conversion to/from UTF-8 byte-encoding can, in theory, throw + * an {@code UnsupportedEncodingException}. However, UTF-8 encoding + * should be a standard encoding for all Java installations, so an + * {@code UnsupportedEncodingException} never actually be thrown. Therefore, + * in order to keep client code uncluttered, any possible + * {@code UnsupportedEncodingException}s will be first logged, and then + * re-thrown as a {@code RuntimeException} with the original + * {@code UnsupportedEncodingException} as the cause. + *

+ * Copyright © 2009 - The OWASP Foundation + *

+ * @author kevin.w.wall@gmail.com + * @see CipherText + * @since 2.0 + */ +public final class PlainText implements Serializable { + + private static final long serialVersionUID = 20090921; + private static Logger logger = ESAPI.getLogger("PlainText"); + + private byte[] rawBytes = null; + + /** + * Construct a {@code PlainText} object from a {@code String}. + * @param str The {@code String} that is converted to a UTF-8 encoded + * byte array to create the {@code PlainText} object. + * @throws IllegalArgumentException If {@code str} argument is null. + */ + public PlainText(String str) { + try { + if ( str == null ) { + throw new IllegalArgumentException("String for plaintext may not be null!"); + } + rawBytes = str.getBytes("UTF-8"); + } catch (UnsupportedEncodingException e) { + // Should never happen. + logger.error(Logger.EVENT_FAILURE, "PlainText(String) CTOR failed: Can't find UTF-8 byte-encoding!", e); + throw new RuntimeException("Can't find UTF-8 byte-encoding!", e); + } + } + + /** + * Construct a {@code PlainText} object from a {@code byte} array. + * @param b The {@code byte} array used to create the {@code PlainText} + * object. + */ + public PlainText(byte[] b) { + // Must allow 0 length arrays though, to represent empty strings. + if ( b == null ) { + throw new IllegalArgumentException("Byte array representing plaintext cannot be null."); + } + + // Make copy so mutable byte array b can't change PlainText. + rawBytes = new byte[ b.length ]; + System.arraycopy(b, 0, rawBytes, 0, b.length); + } + + /** + * Convert the {@code PlainText} object to a UTF-8 encoded {@code String}. + * @return A {@code String} representing the {@code PlainText} object. + */ + public String toString() { + try { + return new String(rawBytes, "UTF-8"); + } catch (UnsupportedEncodingException e) { + // Should never happen. + logger.error(Logger.EVENT_FAILURE, "PlainText.toString() failed: Can't find UTF-8 byte-encoding!", e); + throw new RuntimeException("Can't find UTF-8 byte-encoding!", e); + } + } + + /** + * Convert the {@code PlainText} object to a byte array. + * @return A byte array representing the {@code PlainText} object. + */ + public byte[] asBytes() { + byte[] bytes = new byte[ rawBytes.length ]; + System.arraycopy(rawBytes, 0, bytes, 0, rawBytes.length); + return bytes; + } + + /** + * {@inheritDoc} + */ + @Override public boolean equals(Object anObject) { + + if ( this == anObject ) return true; + if ( anObject == null ) return false; + boolean result = false; + if ( anObject instanceof PlainText ) { + PlainText that = (PlainText)anObject; + result = ( that.canEqual(this) && + ( this.toString().equals( that.toString() ) ) + ); + } + return result; + } + + /** + * Same as {@code this.toString().hashCode()}. + * @return {@code this.toString().hashCode()}. + */ + @Override public int hashCode() { + return this.toString().hashCode(); + } + + /** + * Return the length of the UTF-8 encoded byte array representing this + * object. Note that if this object was constructed with the constructor + * {@code PlainText(String str)}, then this length might not necessarily + * agree with {@code str.length()}. + * + * @return The length of the UTF-8 encoded byte array representing this + * object. + */ + public int length() { + return rawBytes.length; + } + + // DISCUSS: Should we set 'rawBytes' to null??? Won't make it eligible for + // GC unless this PlainText object is set to null which can't do + // from here. If we set it to null, most methods will cause + // NullPointerException to be thrown. Also will have to change a + // lot of JUnit tests. + /** + * First overwrite the bytes of plaintext with the character '*'. + */ + public void overwrite() { + CryptoHelper.overwrite( rawBytes ); + // rawBytes = null; // See above comment re: discussion. + } + + /** + * Needed for correct definition of equals for general classes. + * (Technically not needed for 'final' classes though like this class + * though; this will just allow it to work in the future should we + * decide to allow * sub-classing of this class.) + *

+ * See + * How to write an Equality Method in Java + * for full explanation. + *

+ */ + protected boolean canEqual(Object other) { + return (other instanceof PlainText); + } +} diff --git a/src/main/java/org/owasp/esapi/crypto/SecurityProviderLoader.java b/src/main/java/org/owasp/esapi/crypto/SecurityProviderLoader.java new file mode 100644 index 000000000..a5cbd708c --- /dev/null +++ b/src/main/java/org/owasp/esapi/crypto/SecurityProviderLoader.java @@ -0,0 +1,289 @@ +package org.owasp.esapi.crypto; + +import java.security.NoSuchProviderException; +import java.security.Provider; +import java.security.Security; +import java.util.Hashtable; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Logger; + +/** + * This class provides a generic static method that loads a + * {@code java.security.Provider} either by some generic name + * (i.e., {@code Provider.getName()}) or by a fully-qualified class name. + * It is intended to be called dynamically by an application to add a + * specific JCE provider at runtime. + *

+ * If the {@code ESAPI.properties} file has a the property + * {@code ESAPI.PreferredJCEProvider} defined to either a recognized + * JCE provider (see below for list) or a fully qualified path name of + * that JCE provider's {@code Provider} class, then the reference implementation + * of ESAPI cryptography ({@code org.owasp.esapi.reference.crypto.JavaEncryptor}) + * tries to load this specified JCE provider via + * {@link SecurityProviderLoader#insertProviderAt(String,int)}. + *

+ */ +public class SecurityProviderLoader { + private static Logger logger = ESAPI.getLogger("SecurityProviderLoader"); + private static Hashtable jceProviders; + + static { + // + // Load the table with known providers. We load the (short) JCE name + // and the corresponding provider class. We don't 'new' the actual + // class name here because that would mean we would have to have all + // these jars. Instead we use reflection and do it dynamically only + // when SecurityProviderLoader.insertProviderAt() is called because + // presumably they will have the jar in their classpath for the + // provider they wish to use. + // + jceProviders = new Hashtable(); + // SunJCE is installed by default and should always be available + // with Sun-based JREs. As of JDK 1.3 and later, it is part of the + // standard JRE install. + jceProviders.put("SunJCE", "com.sun.crypto.provider.SunJCE"); + + // IBMJCE is default for WebSphere and is used by IBM JDKs. They + // also have IBMJCEFIPS, but not sure if this is *always* provided + // with WebSphere or just an add-on, hence not including it. IBMJCEFIPS + // is a FIPS 140-2 compliant JCE provider from IBM. + jceProviders.put("IBMJCE", "com.ibm.crypto.provider.IBMJCE"); + // jceProviders.put("IBMJCEFIPS", "com.ibm.crypto.fips.provider.IBMJCEFIPS"); + + // GnuCrypto is JCE provider for GNU Compiler for Java (GCJ) + jceProviders.put("GnuCrypto", "gnu.crypto.jce.GnuCrypto"); + + // Bouncy Castle -- http://www.bouncycastle.org/ - FOSS, maintained. + jceProviders.put("BC", + "org.bouncycastle.jce.provider.BouncyCastleProvider"); + + // IAIK -- http://jce.iaik.tugraz.at/ -- No longer free. + jceProviders.put("IAIK", "iaik.security.provider.IAIK"); + + // IBM FIPS 140-2 compliant provider -- Commercial + // See above comments. + // jceProviders.put("IBMJCEFIPS", "com.ibm.crypto.fips.provider.IBMJCEFIPS"); + + // RSA FIPS 142-2 compliant provider -- Commercial + // jceProviders.put("RSA", "com.rsa.jsafe.crypto.CryptoJ"); + + // Cryptix -- http://www.cryptix.org/ - FOSS, not maintained. + // Cryptix JCE code signing cert expired 2009/08/29 and was not + // renewed. + jceProviders.put("CryptixCrypto", "cryptix.jce.provider.CryptixCrypto"); + jceProviders.put("Cryptix", "cryptix.jce.provider.CryptixCrypto"); + + // ABA - FOSS, not maintained - Google for it, or maybe search for + // old copy at http://www.archive.org/ + jceProviders.put("ABA", "au.net.aba.crypto.provider.ABAProvider"); + } + + /** + * This methods adds a provider to the {@code SecurityManager} + * either by some generic name or by the class name. + *

+ * The following generic JCE provider names are built-in: + *

    + *
  • SunJCE
  • + *
  • IBMJCE [for WebSphere]
  • + *
  • GnuCrypto [for use with GNU Compiler for Java, i.e., gcj]
  • + *
  • BC [i.e., Bouncy Castle]
  • + *
  • IAIK
  • + *
  • CryptixCrypto (or Cryptix) + *
  • ABA + *
+ * Note that neither Cryptix or ABA are actively maintained so + * it is recommended that you do not start using them for ESAPI + * unless your application already has a dependency on them. Furthermore, + * the Cryptix JCE jars likely will not work as the Cryptix code signing + * certificate has expired as of August 28, 2009. (This likely is true + * for ABA, but I can't even find a copy to download!). Lastly, the IAIK + * provider is no longer offered as free, open source. It is not a + * commercial product. See {@link "http://jce.iaik.tugraz.at/"} for + * details. While some older versions were offered free, it is not clear + * whether the accompanying license still allows you to use it, and if + * it does, whether or not the code signing certificate used to sign + * their JCE jar(s) has expired are not. Therefore, if you are looking + * for a FOSS alternative to SunJCE, Bouncy Castle + * ({@link "http://www.bouncycastle.org/"} is probably your best bet. The + * BC provider does support many the "combined cipher modes" that provide + * both confidentiality and authenticity. (See the {@code ESAPI.properties} + * property {@code Encryptor.cipher_modes.combined_modes} for details.) + *

+ * For those working in the U.S. federal government, it should be noted + * that none of the providers listed here are considered validated + * by NIST's Cryptographic Module Validation Program and are therefore + * not considered FIPS 140-2 compliant. There are a few approved + * JCE compatible Java libraries that are on NIST's CMVP list, but this + * list changes constantly so they are not listed here. For further details + * on NIST's CMVP, see + * {@link "http://csrc.nist.gov/groups/STM/cmvp/index.html"}. + *

+ * Finally, if you wish to use some other JCE provider not recognized above, + * you must specify the provider's fully-qualified class name (which in + * turn must have a public, no argument constructor). + *

+ * The application must be given the {@code SecurityPermission} with a + * value of {@code insertProvider.<provider_name>} (where + * <provider_name> is the name of the algorithm provider if + * a security manager is installed. + *

+ * + * @param algProvider Name of the JCE algorithm provider. If the name + * contains a ".", this is interpreted as the name + * of a {@code java.security.Provider} class name. + * @param pos The preference position (starting at 1) that the + * caller would like for this provider. If you wish + * for it to be installed as the last provider + * (as of the time of this call), set {@code pos} to -1. + * @return The actual preference position at which the provider was added, + * or -1 if the provider was not added because it is already + * installed. + * @exception NoSuchProviderException - thrown if the provider class + * could not be loaded or added to the {@code SecurityManager} or + * any other reason for failure. + */ + public static int insertProviderAt(String algProvider, int pos) + throws NoSuchProviderException + { + // We assume that if the algorithm provider contains a ".", then + // we interpret this as a crypto provider class name and dynamically + // add the provider. If it's one of the special ones we know about, + // we also dynamically create it. Otherwise, we assume the provider + // is in the "java.security" file. + Class providerClass = null; + String clzName = null; + Provider cryptoProvider = null; + + // Yes; I'm aware of DeMorgan's Law, but this is easier to grok. + if ( ! ( (pos == -1 || pos >= 1) ) ) { + throw new IllegalArgumentException("Position pos must be -1 or integer >= 1"); + } + + try { + // Does algProvider look like a class name? + if (algProvider.indexOf('.') != -1) { + clzName = algProvider; + } else if ( jceProviders.containsKey(algProvider) ) { + // One of the special cases we know about. + clzName = jceProviders.get(algProvider); + } else { + throw new NoSuchProviderException("Unable to locate Provider class for " + + "provider " + algProvider + ". Try using fully qualified class name " + + "or check provider name for typos. Builtin provider names are: " + + jceProviders.toString()); + } + + providerClass = Class.forName(clzName); + cryptoProvider = (Provider)providerClass.newInstance(); + + // Found from above. Note that Security.insertProviderAt() can + // throw a SecurityException if a Java SecurityManager is + // installed and application doesn't have appropriate + // permissions in policy file. + // + // However, since SecurityException is a RuntimeException it + // doesn't need to be explicitly declared on the throws clause. + // The application must be given the SecurityPermission with + // a value of "insertProvider." (where + // is the name of the algorithm provider) if + // a SecurityManager is installed. + int ret; + if ( pos == -1 ) { // Special case: Means place _last_. + ret = Security.addProvider(cryptoProvider); + } else { + ret = Security.insertProviderAt(cryptoProvider, pos); + } + if ( ret == -1 ) { + // log INFO that provider was already loaded. + String msg = "JCE provider '" + algProvider + "' already loaded"; + if (pos == -1) { + // The just wanted it available (loaded last) and it is, so + // this is not critical. + logger.always(Logger.SECURITY_SUCCESS, msg); + } else { + // In this case, it's a warning because it may have already + // been loaded, but *after* the position they requested. + // For example, if they were trying to load a FIPS 140-2 + // compliant JCE provider at the first position and it was + // already loaded at position 3, then this is not FIPS 140-2 + // compliant. Therefore, we make it a warning and a failure. + // Also log separately using 'always' in case warnings suppressed + // as per NSA suggestion. + logger.warning(Logger.SECURITY_FAILURE, msg); + logger.always(Logger.SECURITY_FAILURE, "(audit) " + msg); + } + } else { + // As per NSA suggestion. + logger.always(Logger.SECURITY_AUDIT, + "Successfully loaded preferred JCE provider " + + algProvider + " at position " + pos); + } + return ret; + } catch(SecurityException ex) { + // CHECKME: Log security event here too? This is a RuntimeException. + // It would only be thrown if a SecurityManager is installed that + // prohibits Security.addProvider() or Security.insertProviderAt() + // by the current user of this thread. Will log it here. Can always + // be ignored. + logger.always(Logger.SECURITY_FAILURE, "Failed to load preferred JCE provider " + + algProvider + " at position " + pos, ex); + throw ex; + } catch(Exception ex) { + // Possibilities include: ClassNotFoundException, + // InstantiationException, and others??? + // + // Log an error & re-throw original message as NoSuchProviderException, + // since that what it probably really implied here. This probably a configuration + // error (e.g., classpath problem, etc.) so we use EVENT_FAILURE rather than + // SECURITY_FAILURE here. + logger.error(Logger.EVENT_FAILURE, "Failed to insert failed crypto " + + " provider " + algProvider + " at position " + pos, ex); + throw new NoSuchProviderException("Failed to insert crypto " + + " provider for " + algProvider + + "; exception msg: " + ex.toString()); + } + } + + /** + * Load the preferred JCE provider for ESAPI based on the ESAPI.properties + * property {@code Encryptor.PreferredJCEProvider}. If this property is null + * (i.e., unset) or set to an empty string, then no JCE provider is inserted + * at the "preferred" position and thus the Java VM continues to use whatever + * the default it was using for this (generally specified in the file + * {@code $JAVA_HOME/jre/security/java.security}). + * @return The actual preference position at which the provider was added, + * (which is expected to be 1) or -1 if the provider was not added + * because it is already installed at some other position. -1 is also + * returned if the {@code Encryptor.PreferredJCEProvider} was not set + * or set to an empty string, i.e., if the application has no + * preferred JCE provider. + * @exception NoSuchProviderException - thrown if the provider class + * could not be loaded or added to the {@code SecurityManager} or + * any other reason for failure. + * @see + * ESAPI 2.0 Symmetric Encryption User Guide + */ + public static int loadESAPIPreferredJCEProvider() throws NoSuchProviderException + { + String prefJCEProvider = + ESAPI.securityConfiguration().getPreferredJCEProvider(); + try { + // If unset or set to empty string, then don't try to change it. + if ( prefJCEProvider == null || prefJCEProvider.trim().length() == 0) { + // Always log, per NSA suggestion. + logger.always(Logger.SECURITY_AUDIT, "No Encryptor.PreferredJCEProvider specified."); + return -1; // Unchanged; it is, whatever it is. + } else { + return insertProviderAt(prefJCEProvider, 1); + } + } catch (NoSuchProviderException ex) { + // Will already have logged with exception msg. + String msg = "failed to load *preferred* " + "JCE crypto provider, " + prefJCEProvider; + logger.always(Logger.SECURITY_AUDIT, msg); // Per NSA suggestion. + logger.error(Logger.SECURITY_FAILURE, msg); + throw ex; + } + } +} diff --git a/src/main/java/org/owasp/esapi/crypto/package.html b/src/main/java/org/owasp/esapi/crypto/package.html new file mode 100644 index 000000000..fcca55e9b --- /dev/null +++ b/src/main/java/org/owasp/esapi/crypto/package.html @@ -0,0 +1,10 @@ + + + + + + +This package contains ESAPI cryptography-related classes used throughout +ESAPI. + + \ No newline at end of file diff --git a/javadoc/org/owasp/esapi/doc-files/AccessController.jpg b/src/main/java/org/owasp/esapi/doc-files/AccessController.jpg similarity index 100% rename from javadoc/org/owasp/esapi/doc-files/AccessController.jpg rename to src/main/java/org/owasp/esapi/doc-files/AccessController.jpg diff --git a/javadoc/org/owasp/esapi/doc-files/AccessReferenceMap.jpg b/src/main/java/org/owasp/esapi/doc-files/AccessReferenceMap.jpg similarity index 100% rename from javadoc/org/owasp/esapi/doc-files/AccessReferenceMap.jpg rename to src/main/java/org/owasp/esapi/doc-files/AccessReferenceMap.jpg diff --git a/javadoc/org/owasp/esapi/doc-files/Architecture.jpg b/src/main/java/org/owasp/esapi/doc-files/Architecture.jpg similarity index 100% rename from javadoc/org/owasp/esapi/doc-files/Architecture.jpg rename to src/main/java/org/owasp/esapi/doc-files/Architecture.jpg diff --git a/javadoc/org/owasp/esapi/doc-files/Authenticator.jpg b/src/main/java/org/owasp/esapi/doc-files/Authenticator.jpg similarity index 100% rename from javadoc/org/owasp/esapi/doc-files/Authenticator.jpg rename to src/main/java/org/owasp/esapi/doc-files/Authenticator.jpg diff --git a/src/main/java/org/owasp/esapi/doc-files/Encryptor.jpg b/src/main/java/org/owasp/esapi/doc-files/Encryptor.jpg new file mode 100644 index 000000000..a52da895b Binary files /dev/null and b/src/main/java/org/owasp/esapi/doc-files/Encryptor.jpg differ diff --git a/javadoc/org/owasp/esapi/doc-files/HTTPUtilities.jpg b/src/main/java/org/owasp/esapi/doc-files/HTTPUtilities.jpg similarity index 100% rename from javadoc/org/owasp/esapi/doc-files/HTTPUtilities.jpg rename to src/main/java/org/owasp/esapi/doc-files/HTTPUtilities.jpg diff --git a/javadoc/org/owasp/esapi/doc-files/IntrusionDetector.jpg b/src/main/java/org/owasp/esapi/doc-files/IntrusionDetector.jpg similarity index 100% rename from javadoc/org/owasp/esapi/doc-files/IntrusionDetector.jpg rename to src/main/java/org/owasp/esapi/doc-files/IntrusionDetector.jpg diff --git a/javadoc/org/owasp/esapi/doc-files/OWASPTopTen.jpg b/src/main/java/org/owasp/esapi/doc-files/OWASPTopTen.jpg similarity index 100% rename from javadoc/org/owasp/esapi/doc-files/OWASPTopTen.jpg rename to src/main/java/org/owasp/esapi/doc-files/OWASPTopTen.jpg diff --git a/javadoc/org/owasp/esapi/doc-files/Validator.jpg b/src/main/java/org/owasp/esapi/doc-files/Validator.jpg similarity index 100% rename from javadoc/org/owasp/esapi/doc-files/Validator.jpg rename to src/main/java/org/owasp/esapi/doc-files/Validator.jpg diff --git a/src/main/java/org/owasp/esapi/errors/AccessControlException.java b/src/main/java/org/owasp/esapi/errors/AccessControlException.java new file mode 100644 index 000000000..fbc537f3d --- /dev/null +++ b/src/main/java/org/owasp/esapi/errors/AccessControlException.java @@ -0,0 +1,57 @@ +/** + * 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.errors; + +/** + * An AccessControlException should be thrown when a user attempts to access a + * resource that they are not authorized for. + * + * @author Jeff Williams (jeff.williams@aspectsecurity.com) + */ +public class AccessControlException extends EnterpriseSecurityException { + + /** The Constant serialVersionUID. */ + private static final long serialVersionUID = 1L; + + /** + * Instantiates a new access control exception. + */ + protected AccessControlException() { + // hidden + } + + /** + * Creates a new instance of {@code AccessControlException}. + * + * @param userMessage + * @param logMessage + */ + public AccessControlException(String userMessage, String logMessage) { + super(userMessage, logMessage); + } + + /** + * Instantiates a new access control exception. + * + * @param userMessage the message displayed to the user + * @param logMessage the message logged + * @param cause the root cause + */ + public AccessControlException(String userMessage, String logMessage, Throwable cause) { + super(userMessage, logMessage, cause); + } + +} diff --git a/src/main/java/org/owasp/esapi/errors/AuthenticationAccountsException.java b/src/main/java/org/owasp/esapi/errors/AuthenticationAccountsException.java new file mode 100644 index 000000000..a08b02c88 --- /dev/null +++ b/src/main/java/org/owasp/esapi/errors/AuthenticationAccountsException.java @@ -0,0 +1,59 @@ +/** + * 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.errors; + +/** + * An AuthenticationException should be thrown when anything goes wrong during + * login or logout. They are also appropriate for any problems related to + * identity management. + * + * @author Jeff Williams (jeff.williams@aspectsecurity.com) + */ +public class AuthenticationAccountsException extends AuthenticationException { + + /** The Constant serialVersionUID. */ + private static final long serialVersionUID = 1L; + + /** + * Instantiates a new authentication exception. + */ + protected AuthenticationAccountsException() { + // hidden + } + + /** + * Creates a new instance of {@code AuthenticationAccountsException}. + * + * @param userMessage the message displayed to the user + * @param logMessage the message logged + * + */ + public AuthenticationAccountsException(String userMessage, String logMessage) { + super(userMessage, logMessage); + } + + /** + * Instantiates a new authentication exception. + * + * @param userMessage the message displayed to the user + * @param logMessage the message logged + * @param cause the root cause + */ + public AuthenticationAccountsException(String userMessage, String logMessage, Throwable cause) { + super(userMessage, logMessage, cause); + } + +} diff --git a/src/main/java/org/owasp/esapi/errors/AuthenticationCredentialsException.java b/src/main/java/org/owasp/esapi/errors/AuthenticationCredentialsException.java new file mode 100644 index 000000000..ad3d8df6b --- /dev/null +++ b/src/main/java/org/owasp/esapi/errors/AuthenticationCredentialsException.java @@ -0,0 +1,58 @@ +/** + * 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.errors; + +/** + * An AuthenticationException should be thrown when anything goes wrong during + * login or logout. They are also appropriate for any problems related to + * identity management. + * + * @author Jeff Williams (jeff.williams@aspectsecurity.com) + */ +public class AuthenticationCredentialsException extends AuthenticationException { + + /** The Constant serialVersionUID. */ + private static final long serialVersionUID = 1L; + + /** + * Instantiates a new authentication exception. + */ + protected AuthenticationCredentialsException() { + // hidden + } + + /** + * Creates a new instance of {@code AuthenticationCredentialsException}. + * + * @param userMessage the message displayed to the user + * @param logMessage the message logged + */ + public AuthenticationCredentialsException(String userMessage, String logMessage) { + super(userMessage, logMessage); + } + + /** + * Instantiates a new authentication exception. + * + * @param userMessage the message displayed to the user + * @param logMessage the message logged + * @param cause the root cause + */ + public AuthenticationCredentialsException(String userMessage, String logMessage, Throwable cause) { + super(userMessage, logMessage, cause); + } + +} diff --git a/src/main/java/org/owasp/esapi/errors/AuthenticationException.java b/src/main/java/org/owasp/esapi/errors/AuthenticationException.java new file mode 100644 index 000000000..55abbc370 --- /dev/null +++ b/src/main/java/org/owasp/esapi/errors/AuthenticationException.java @@ -0,0 +1,58 @@ +/** + * 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.errors; + +/** + * An AuthenticationException should be thrown when anything goes wrong during + * login or logout. They are also appropriate for any problems related to + * identity management. + * + * @author Jeff Williams (jeff.williams@aspectsecurity.com) + */ +public class AuthenticationException extends EnterpriseSecurityException { + + /** The Constant serialVersionUID. */ + private static final long serialVersionUID = 1L; + + /** + * Instantiates a new authentication exception. + */ + protected AuthenticationException() { + // hidden + } + + /** + * Creates a new instance of {@code AuthenticationException}. + * + * @param userMessage the message displayed to the user + * @param logMessage the message logged + */ + public AuthenticationException(String userMessage, String logMessage) { + super(userMessage, logMessage); + } + + /** + * Instantiates a new authentication exception. + * + * @param userMessage the message displayed to the user + * @param logMessage the message logged + * @param cause the root cause + */ + public AuthenticationException(String userMessage, String logMessage, Throwable cause) { + super(userMessage, logMessage, cause); + } + +} diff --git a/src/main/java/org/owasp/esapi/errors/AuthenticationHostException.java b/src/main/java/org/owasp/esapi/errors/AuthenticationHostException.java new file mode 100644 index 000000000..4010d79b1 --- /dev/null +++ b/src/main/java/org/owasp/esapi/errors/AuthenticationHostException.java @@ -0,0 +1,57 @@ +/** + * 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.errors; + +/** + * An AuthenticationHostException should be thrown when there is a problem with + * the host involved with authentication, particularly if the host changes unexpectedly. + * + * @author Jeff Williams (jeff.williams@aspectsecurity.com) + */ +public class AuthenticationHostException extends AuthenticationException { + + /** The Constant serialVersionUID. */ + private static final long serialVersionUID = 1L; + + /** + * Instantiates a new authentication exception. + */ + protected AuthenticationHostException() { + // hidden + } + + /** + * Creates a new instance of AuthenticationHostException. + * + * @param userMessage the message displayed to the user + * @param logMessage the message logged + */ + public AuthenticationHostException(String userMessage, String logMessage) { + super(userMessage, logMessage); + } + + /** + * Instantiates a new authentication exception. + * + * @param userMessage the message displayed to the user + * @param logMessage the message logged + * @param cause the cause + */ + public AuthenticationHostException(String userMessage, String logMessage, Throwable cause) { + super(userMessage, logMessage, cause); + } + +} diff --git a/src/main/java/org/owasp/esapi/errors/AuthenticationLoginException.java b/src/main/java/org/owasp/esapi/errors/AuthenticationLoginException.java new file mode 100644 index 000000000..0f7a3d855 --- /dev/null +++ b/src/main/java/org/owasp/esapi/errors/AuthenticationLoginException.java @@ -0,0 +1,58 @@ +/** + * 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.errors; + +/** + * An AuthenticationException should be thrown when anything goes wrong during + * login or logout. They are also appropriate for any problems related to + * identity management. + * + * @author Jeff Williams (jeff.williams@aspectsecurity.com) + */ +public class AuthenticationLoginException extends AuthenticationException { + + /** The Constant serialVersionUID. */ + private static final long serialVersionUID = 1L; + + /** + * Instantiates a new authentication exception. + */ + protected AuthenticationLoginException() { + // hidden + } + + /** + * Creates a new instance of EnterpriseSecurityException. + * + * @param userMessage the message displayed to the user + * @param logMessage the message logged + */ + public AuthenticationLoginException(String userMessage, String logMessage) { + super(userMessage, logMessage); + } + + /** + * Instantiates a new authentication exception. + * + * @param userMessage the message displayed to the user + * @param logMessage the message logged + * @param cause the cause + */ + public AuthenticationLoginException(String userMessage, String logMessage, Throwable cause) { + super(userMessage, logMessage, cause); + } + +} diff --git a/src/main/java/org/owasp/esapi/errors/AvailabilityException.java b/src/main/java/org/owasp/esapi/errors/AvailabilityException.java new file mode 100644 index 000000000..98099155d --- /dev/null +++ b/src/main/java/org/owasp/esapi/errors/AvailabilityException.java @@ -0,0 +1,57 @@ +/** + * 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.errors; + +/** + * 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. + * + * @author Jeff Williams (jeff.williams@aspectsecurity.com) + */ +public class AvailabilityException extends EnterpriseSecurityException { + + /** The Constant serialVersionUID. */ + private static final long serialVersionUID = 1L; + + /** + * Instantiates a new availability exception. + */ + protected AvailabilityException() { + // hidden + } + + /** + * Creates a new instance of AvailabilityException. + * + * @param userMessage the message displayed to the user + * @param logMessage the message logged + */ + public AvailabilityException(String userMessage, String logMessage) { + super(userMessage, logMessage); + } + + /** + * Instantiates a new AvailabilityException. + * + * @param userMessage the message displayed to the user + * @param logMessage the message logged + * @param cause the cause + */ + public AvailabilityException(String userMessage, String logMessage, Throwable cause) { + super(userMessage, logMessage, cause); + } +} diff --git a/src/main/java/org/owasp/esapi/errors/CertificateException.java b/src/main/java/org/owasp/esapi/errors/CertificateException.java new file mode 100644 index 000000000..561d41179 --- /dev/null +++ b/src/main/java/org/owasp/esapi/errors/CertificateException.java @@ -0,0 +1,56 @@ +/** + * 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.errors; + +/** + * A CertificateException should be thrown for any problems that arise during + * processing of digital certificates. + * + * @author Jeff Williams (jeff.williams@aspectsecurity.com) + */ +public class CertificateException extends EnterpriseSecurityException { + + /** The Constant serialVersionUID. */ + private static final long serialVersionUID = 1L; + + /** + * Instantiates a new certificate exception. + */ + protected CertificateException() { + // hidden + } + + /** + * Creates a new instance of CertificateException. + * + * @param userMessage the message displayed to the user + * @param logMessage the message logged + */ + public CertificateException(String userMessage, String logMessage) { + super(userMessage, logMessage); + } + + /** + * Instantiates a new CertificateException. + * + * @param userMessage the message displayed to the user + * @param logMessage the message logged + * @param cause the cause + */ + public CertificateException(String userMessage, String logMessage, Throwable cause) { + super(userMessage, logMessage, cause); + } +} diff --git a/src/main/java/org/owasp/esapi/errors/ConfigurationException.java b/src/main/java/org/owasp/esapi/errors/ConfigurationException.java new file mode 100644 index 000000000..17d6a6b3e --- /dev/null +++ b/src/main/java/org/owasp/esapi/errors/ConfigurationException.java @@ -0,0 +1,34 @@ +package org.owasp.esapi.errors; + +/** + * A {@code ConfigurationException} should be thrown when a problem arises because of + * a problem in one of ESAPI's configuration files, such as a missing required + * property or invalid setting of a property, or missing or unreadable + * configuration file, etc. + *

+ * A {@code ConfigurationException} is a {@code RuntimeException} + * because 1) configuration properties can, for the most part, only be checked + * at run-time, and 2) we want this to be an unchecked exception to make ESAPI + * easy to use and not cluttered with catching a bunch of try/catch blocks. + *

+ */ +public class ConfigurationException extends RuntimeException { + + protected static final long serialVersionUID = 1L; + + public ConfigurationException(Exception e) { + super(e); + } + + public ConfigurationException(String s) { + super(s); + } + + public ConfigurationException(String s, Throwable cause) { + super(s, cause); + } + + public ConfigurationException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/org/owasp/esapi/errors/EncodingException.java b/src/main/java/org/owasp/esapi/errors/EncodingException.java new file mode 100644 index 000000000..cee3abf2b --- /dev/null +++ b/src/main/java/org/owasp/esapi/errors/EncodingException.java @@ -0,0 +1,62 @@ +/** + * 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.errors; + +/** + * An EncodingException should be thrown for any problems that occur when + * encoding or decoding data. + * + * @author Jeff Williams (jeff.williams@aspectsecurity.com) + */ +public class EncodingException extends EnterpriseSecurityException { + + /** The Constant serialVersionUID. */ + private static final long serialVersionUID = 1L; + + /** + * Instantiates a new service exception. + */ + protected EncodingException() { + // hidden + } + + /** + * Creates a new instance of EncodingException. + * + * @param userMessage + * the message displayed to the user + * @param logMessage + * the message logged + */ + public EncodingException(String userMessage, String logMessage) { + super(userMessage, logMessage); + } + + /** + * Instantiates a new EncodingException. + * + * @param userMessage + * the message displayed to the user + * @param logMessage + * the message logged + * @param cause + * the cause + */ + public EncodingException(String userMessage, String logMessage, Throwable cause) { + super(userMessage, logMessage, cause); + } + +} diff --git a/src/main/java/org/owasp/esapi/errors/EncryptionException.java b/src/main/java/org/owasp/esapi/errors/EncryptionException.java new file mode 100644 index 000000000..895d34eb7 --- /dev/null +++ b/src/main/java/org/owasp/esapi/errors/EncryptionException.java @@ -0,0 +1,61 @@ +/** + * 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.errors; + +/** + * An EncryptionException should be thrown for any problems related to + * encryption, hashing, or digital signatures. + * + * @author Jeff Williams (jeff.williams@aspectsecurity.com) + */ +public class EncryptionException extends EnterpriseSecurityException { + + /** The Constant serialVersionUID. */ + private static final long serialVersionUID = 1L; + + /** + * Instantiates a new EncryptionException. + */ + protected EncryptionException() { + // hidden + } + + /** + * Creates a new instance of EncryptionException. + * + * @param userMessage + * the message displayed to the user + * @param logMessage + * the message logged + */ + public EncryptionException(String userMessage, String logMessage) { + super(userMessage, logMessage); + } + + /** + * Instantiates a new EncryptionException. + * + * @param userMessage + * the message displayed to the user + * @param logMessage + * the message logged + * @param cause + * the cause + */ + public EncryptionException(String userMessage, String logMessage, Throwable cause) { + super(userMessage, logMessage, cause); + } +} diff --git a/src/main/java/org/owasp/esapi/errors/EncryptionRuntimeException.java b/src/main/java/org/owasp/esapi/errors/EncryptionRuntimeException.java new file mode 100644 index 000000000..cdc484324 --- /dev/null +++ b/src/main/java/org/owasp/esapi/errors/EncryptionRuntimeException.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) 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 Jeff Williams Aspect Security + * @created 2007 + */ +package org.owasp.esapi.errors; + +/** + * An EncryptionRuntimeException should be thrown for any problems related to + * encryption, hashing, or digital signatures. + * + * @author August Detlefsen (augustd at codemagi dot com) + * CodeMagi, Inc. + * @since October 8, 2010 + */ +public class EncryptionRuntimeException extends EnterpriseSecurityRuntimeException { + + /** The Constant serialVersionUID. */ + private static final long serialVersionUID = 1L; + + /** + * Instantiates a new EncryptionException. + */ + protected EncryptionRuntimeException() { + // hidden + } + + /** + * Creates a new instance of EncryptionException. + * + * @param userMessage + * the message displayed to the user + * @param logMessage + * the message logged + */ + public EncryptionRuntimeException(String userMessage, String logMessage) { + super(userMessage, logMessage); + } + + /** + * Instantiates a new EncryptionException. + * + * @param userMessage + * the message displayed to the user + * @param logMessage + * the message logged + * @param cause + * the cause + */ + public EncryptionRuntimeException(String userMessage, String logMessage, Throwable cause) { + super(userMessage, logMessage, cause); + } +} diff --git a/src/main/java/org/owasp/esapi/errors/EnterpriseSecurityException.java b/src/main/java/org/owasp/esapi/errors/EnterpriseSecurityException.java new file mode 100644 index 000000000..6b150bb42 --- /dev/null +++ b/src/main/java/org/owasp/esapi/errors/EnterpriseSecurityException.java @@ -0,0 +1,152 @@ +/** + * 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.errors; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Logger; + +import static org.owasp.esapi.PropNames.DISABLE_INTRUSION_DETECTION; + + +/** + * 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 anomalous patterns of + * application usage. + *

+ * @author Jeff Williams (jeff.williams@aspectsecurity.com) + */ +public class EnterpriseSecurityException extends Exception { + + protected static final long serialVersionUID = 1L; + + /** The logger. */ + protected final transient Logger logger = ESAPI.getLogger("EnterpriseSecurityException"); + + /** + * + */ + protected String logMessage = null; + + /** + * Instantiates a new enterprise security exception. + */ + protected EnterpriseSecurityException() { + // hidden + } + + /** + * Instantiates a new enterprise security exception with a user message. + * (Needed by anything which subclasses this.) + * + * @param userMessage Message displayed to user. + */ + protected EnterpriseSecurityException(String userMessage) { + // hidden + super(userMessage); + } + + /** + * Instantiates a new enterprise security exception with a user message + * and cause. (Needed by anything which subclasses this.) + * + * @param userMessage Message displayed to user. + * @param cause The cause (which is saved for later retrieval by the + * getCause() method). (A null value is permitted, and indicates that the + * cause is nonexistent or unknown.) + */ + protected EnterpriseSecurityException(String userMessage, Throwable cause) + { + // hidden + super(userMessage, cause); + } + + /** + * 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. + * + * It should be noted that messages that are intended to be displayed to the user should be safe for display. In + * other words, don't pass in unsanitized data here. Also could hold true for the logging message depending on the + * context of the exception. + * + * @param userMessage + * the message displayed to the user + * @param logMessage + * the message logged + */ + public EnterpriseSecurityException(String userMessage, String logMessage) { + super(userMessage); + this.logMessage = logMessage; + if (!ESAPI.securityConfiguration().getBooleanProp( DISABLE_INTRUSION_DETECTION )) { + ESAPI.intrusionDetector().addException(this); + } + } + + /** + * Creates a new instance of EnterpriseSecurityException that includes a root cause Throwable. + * + * It should be noted that messages that are intended to be displayed to the user should be safe for display. In + * other words, don't pass in unsanitized data here. Also could hold true for the logging message depending on the + * context of the exception. + * + * @param userMessage + * the message displayed to the user + * @param logMessage + * the message logged + * @param cause the cause + */ + public EnterpriseSecurityException(String userMessage, String logMessage, Throwable cause) { + super(userMessage, cause); + this.logMessage = logMessage; + if (!ESAPI.securityConfiguration().getBooleanProp( DISABLE_INTRUSION_DETECTION )) { + ESAPI.intrusionDetector().addException(this); + } + } + + /** + * Returns message meant for display to users + * + * Note that if you are unsure of what set this message, it would probably + * be a good idea to encode this message before displaying it to the end user. + * + * @return a String containing a message that is safe to display to users + */ + public String getUserMessage() { + return getMessage(); + } + + /** + * Returns a message that is safe to display in logs, but may contain + * sensitive information and therefore probably should not be displayed to + * users. + * + * @return a String containing a message that is safe to display in logs, + * but probably not to users as it may contain sensitive information. + */ + public String getLogMessage() { + return logMessage; + } + +} diff --git a/src/main/java/org/owasp/esapi/errors/EnterpriseSecurityRuntimeException.java b/src/main/java/org/owasp/esapi/errors/EnterpriseSecurityRuntimeException.java new file mode 100644 index 000000000..3b511c321 --- /dev/null +++ b/src/main/java/org/owasp/esapi/errors/EnterpriseSecurityRuntimeException.java @@ -0,0 +1,153 @@ +/** + * 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 Jeff Williams Aspect Security + * @created 2007 + */ +package org.owasp.esapi.errors; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Logger; + + +/** + * EnterpriseSecurityRuntimeException is the base class for all security related runtime exceptions. You should pass in the root cause + * exception wherever possible. Constructors for classes extending this class should be sure to call the + * appropriate super() method in order to ensure that logging and intrusion detection occur properly. + *

+ * All EnterpriseSecurityRuntimeExceptions 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 EnterpriseSecurityRuntimeExceptions 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 EnterpriseSecurityRuntimeExceptions are also sent to the IntrusionDetector for use in detecting anomalous patterns of + * application usage. + * + * @author August Detlefsen (augustd at codemagi dot com) + * CodeMagi, Inc. + * @since October 8, 2010 + */ +public class EnterpriseSecurityRuntimeException extends java.lang.RuntimeException { + + protected static final long serialVersionUID = 1L; + + /** The logger. */ + protected final Logger logger = ESAPI.getLogger(this.getClass()); + + /** + * + */ + protected String logMessage = null; + + /** + * Instantiates a new enterprise security runtime exception. + */ + protected EnterpriseSecurityRuntimeException() { + // hidden + } + + /** + * Instantiates a new enterprise security runtime exception with a user + * message. (Needed by anything which subclasses this.) + * + * @param userMessage Message displayed to user. + */ + protected EnterpriseSecurityRuntimeException(String userMessage) { + super(userMessage); + } + + /** + * Instantiates a new enterprise security runtime exception with a + * user message and cause. (Needed by anything which subclasses this.) + * + * @param userMessage Message displayed to user. + * @param cause The cause (which is saved for later retrieval by the + * getCause() method). (A null value is permitted, and indicates that the + * cause is nonexistent or unknown.) + */ + protected EnterpriseSecurityRuntimeException(String userMessage, + Throwable cause) + { + // hidden + super(userMessage, cause); + } + + + /** + * 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. + * + * It should be noted that messages that are intended to be displayed to the user should be safe for display. In + * other words, don't pass in unsanitized data here. Also could hold true for the logging message depending on the + * context of the exception. + * + * @param userMessage + * the message displayed to the user + * @param logMessage + * the message logged + */ + public EnterpriseSecurityRuntimeException(String userMessage, String logMessage) { + super(userMessage); + this.logMessage = logMessage; + if (!ESAPI.securityConfiguration().getDisableIntrusionDetection()) { + ESAPI.intrusionDetector().addException(this); + } + } + + /** + * Creates a new instance of EnterpriseSecurityException that includes a root cause Throwable. + * + * It should be noted that messages that are intended to be displayed to the user should be safe for display. In + * other words, don't pass in unsanitized data here. Also could hold true for the logging message depending on the + * context of the exception. + * + * @param userMessage + * the message displayed to the user + * @param logMessage + * the message logged + * @param cause the cause + */ + public EnterpriseSecurityRuntimeException(String userMessage, String logMessage, Throwable cause) { + super(userMessage, cause); + this.logMessage = logMessage; + if (!ESAPI.securityConfiguration().getDisableIntrusionDetection()) { + ESAPI.intrusionDetector().addException(this); + } + } + + /** + * Returns message meant for display to users + * + * Note that if you are unsure of what set this message, it would probably + * be a good idea to encode this message before displaying it to the end user. + * + * @return a String containing a message that is safe to display to users + */ + public String getUserMessage() { + return getMessage(); + } + + /** + * Returns a message that is safe to display in logs, but may contain + * sensitive information and therefore probably should not be displayed to + * users. + * + * @return a String containing a message that is safe to display in logs, + * but probably not to users as it may contain sensitive information. + */ + public String getLogMessage() { + return logMessage; + } + +} diff --git a/src/main/java/org/owasp/esapi/errors/ExecutorException.java b/src/main/java/org/owasp/esapi/errors/ExecutorException.java new file mode 100644 index 000000000..9adda9296 --- /dev/null +++ b/src/main/java/org/owasp/esapi/errors/ExecutorException.java @@ -0,0 +1,62 @@ +/** + * 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.errors; + +/** + * An ExecutorException should be thrown for any problems that arise during the + * execution of a system executable. + * + * @author Jeff Williams (jeff.williams@aspectsecurity.com) + */ +public class ExecutorException extends EnterpriseSecurityException { + + /** The Constant serialVersionUID. */ + private static final long serialVersionUID = 1L; + + /** + * Instantiates a new ExecutorException. + */ + protected ExecutorException() { + // hidden + } + + /** + * Creates a new instance of ExecutorException. + * + * @param userMessage + * the message to display to users + * @param logMessage + * the message logged + */ + public ExecutorException(String userMessage, String logMessage) { + super(userMessage, logMessage); + } + + /** + * Instantiates a new ExecutorException. + * + * @param userMessage + * the message to display to users + * @param logMessage + * the message logged + * @param cause + * the cause + */ + public ExecutorException(String userMessage, String logMessage, Throwable cause) { + super(userMessage, logMessage, cause); + } + +} diff --git a/src/main/java/org/owasp/esapi/errors/IntegrityException.java b/src/main/java/org/owasp/esapi/errors/IntegrityException.java new file mode 100644 index 000000000..92a546a2a --- /dev/null +++ b/src/main/java/org/owasp/esapi/errors/IntegrityException.java @@ -0,0 +1,62 @@ +/** + * 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.errors; + +/** + * An IntegrityException should be thrown when a problem with the integrity of data + * has been detected. For example, if a financial account cannot be reconciled after + * a transaction has been performed, an integrity exception should be thrown. + * + * @author Jeff Williams (jeff.williams@aspectsecurity.com) + */ +public class IntegrityException extends EnterpriseSecurityException { + + /** The Constant serialVersionUID. */ + private static final long serialVersionUID = 1L; + + /** + * Instantiates a new availability exception. + */ + protected IntegrityException() { + // hidden + } + + /** + * Creates a new instance of IntegrityException. + * + * @param userMessage + * the message to display to users + * @param logMessage + * the message logged + */ + public IntegrityException(String userMessage, String logMessage) { + super(userMessage, logMessage); + } + + /** + * Instantiates a new IntegrityException. + * + * @param userMessage + * the message to display to users + * @param logMessage + * the message logged + * @param cause + * the cause + */ + public IntegrityException(String userMessage, String logMessage, Throwable cause) { + super(userMessage, logMessage, cause); + } +} diff --git a/src/main/java/org/owasp/esapi/errors/IntrusionException.java b/src/main/java/org/owasp/esapi/errors/IntrusionException.java new file mode 100644 index 000000000..72261d9e1 --- /dev/null +++ b/src/main/java/org/owasp/esapi/errors/IntrusionException.java @@ -0,0 +1,92 @@ +/** + * 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.errors; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Logger; + +/** + * 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. + * + * @author Jeff Williams (jeff.williams@aspectsecurity.com) + */ +public class IntrusionException extends EnterpriseSecurityRuntimeException { + + /** The Constant serialVersionUID. */ + private static final long serialVersionUID = 1L; + + /** The logger. */ + protected final transient Logger logger = ESAPI.getLogger("IntrusionException"); + + /** + * + */ + protected String logMessage = null; + + /** + * Creates a new instance of IntrusionException. + * + * @param userMessage + * the message to display to users + * @param logMessage + * the message logged + */ + public IntrusionException(String userMessage, String logMessage) { + super(userMessage); + this.logMessage = logMessage; + logger.error(Logger.SECURITY_FAILURE, "INTRUSION - " + logMessage); + } + + /** + * Instantiates a new intrusion exception. + * + * @param userMessage + * the message to display to users + * @param logMessage + * the message logged + * @param cause + * the cause + */ + public IntrusionException(String userMessage, String logMessage, Throwable cause) { + super(userMessage, cause); + this.logMessage = logMessage; + logger.error(Logger.SECURITY_FAILURE, "INTRUSION - " + logMessage, cause); + } + + /** + * Returns a String containing a message that is safe to display to users + * + * @return a String containing a message that is safe to display to users + */ + public String getUserMessage() { + return getMessage(); + } + + /** + * Returns a String that is safe to display in logs, but probably not to users + * + * @return a String containing a message that is safe to display in logs, but probably not to users + */ + public String getLogMessage() { + return logMessage; + } + +} diff --git a/src/main/java/org/owasp/esapi/errors/NotConfiguredByDefaultException.java b/src/main/java/org/owasp/esapi/errors/NotConfiguredByDefaultException.java new file mode 100644 index 000000000..58a0cbc98 --- /dev/null +++ b/src/main/java/org/owasp/esapi/errors/NotConfiguredByDefaultException.java @@ -0,0 +1,34 @@ +package org.owasp.esapi.errors; + +/** + * A {@code NotConfiguredByDefaultException} should be thrown when a method that + * is disabled by default is invoked. + *

+ + * See the ESAPI properties "ESAPI.dangerouslyAllowUnsafeMethods.methodNames" + * and "ESAPI.dangerouslyAllowUnsafeMethods.justification" in the + * ESAPI.properties file for additional details. + *

+ */ +public class NotConfiguredByDefaultException extends ConfigurationException { + + protected static final long serialVersionUID = 1L; + private static final String defaultMsg = "Unknown unsafe ESAPI method invoked without being explicitly allowed. " + + "Check exception stack trace for method name."; + + public NotConfiguredByDefaultException(Exception e) { + super(e); + } + + public NotConfiguredByDefaultException(String s) { + super( (s == null || s.trim().isEmpty()) ? defaultMsg : s); + } + + public NotConfiguredByDefaultException(String s, Throwable cause) { + super( (s == null || s.trim().isEmpty()) ? defaultMsg : s, cause); + } + + public NotConfiguredByDefaultException(Throwable cause) { + super(defaultMsg, cause); + } +} diff --git a/src/main/java/org/owasp/esapi/errors/ValidationAvailabilityException.java b/src/main/java/org/owasp/esapi/errors/ValidationAvailabilityException.java new file mode 100644 index 000000000..5274da5d8 --- /dev/null +++ b/src/main/java/org/owasp/esapi/errors/ValidationAvailabilityException.java @@ -0,0 +1,57 @@ +/** + * 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.errors; + +/** + * @author Jeff Williams (jeff.williams@aspectsecurity.com) + */ +public class ValidationAvailabilityException extends ValidationException { + + /** The Constant serialVersionUID. */ + private static final long serialVersionUID = 1L; + + /** + * Instantiates a new validation exception. + */ + protected ValidationAvailabilityException() { + // hidden + } + + /** + * Create a new ValidationException + * @param userMessage + * the message to display to users + * @param logMessage + * the message logged + */ + public ValidationAvailabilityException(String userMessage, String logMessage) { + super(userMessage, logMessage); + } + + /** + * Create a new ValidationException + * @param userMessage + * the message to display to users + * @param logMessage + * the message logged + * @param cause + * the cause + */ + public ValidationAvailabilityException(String userMessage, String logMessage, Throwable cause) { + super(userMessage, logMessage, cause); + } + +} diff --git a/src/main/java/org/owasp/esapi/errors/ValidationException.java b/src/main/java/org/owasp/esapi/errors/ValidationException.java new file mode 100644 index 000000000..c185574fb --- /dev/null +++ b/src/main/java/org/owasp/esapi/errors/ValidationException.java @@ -0,0 +1,115 @@ +/** + * 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.errors; + +/** + * 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. + * + * @author Jeff Williams (jeff.williams@aspectsecurity.com) + */ +public class ValidationException extends EnterpriseSecurityException { + + protected static final long serialVersionUID = 1L; + + /** The UI reference that caused this ValidationException */ + private String context; + + /** + * Instantiates a new validation exception. + */ + protected ValidationException() { + // hidden + } + + /** + * Creates a new instance of ValidationException. + * + * @param userMessage + * the message to display to users + * @param logMessage + * the message logged + */ + public ValidationException(String userMessage, String logMessage) { + super(userMessage, logMessage); + } + + /** + * Instantiates a new ValidationException. + * + * @param userMessage + * the message to display to users + * @param logMessage + * the message logged + * @param cause + * the cause + */ + public ValidationException(String userMessage, String logMessage, Throwable cause) { + super(userMessage, logMessage, cause); + } + + /** + * Creates a new instance of ValidationException. + * + * @param userMessage + * the message to display to users + * @param logMessage + * the message logged + * @param context + * the source that caused this exception + */ + public ValidationException(String userMessage, String logMessage, String context) { + super(userMessage, logMessage); + setContext(context); + } + + /** + * Instantiates a new ValidationException. + * + * @param userMessage + * the message to display to users + * @param logMessage + * the message logged + * @param cause + * the cause + * @param context + * the source that caused this exception + */ + public ValidationException(String userMessage, String logMessage, Throwable cause, String context) { + super(userMessage, logMessage, cause); + setContext(context); + } + + /** + * Returns the UI reference that caused this ValidationException + * + * @return context, the source that caused the exception, stored as a string + */ + public String getContext() { + return context; + } + + /** + * Set's the UI reference that caused this ValidationException + * + * @param context + * the context to set, passed as a String + */ + public void setContext(String context) { + this.context = context; + } +} diff --git a/src/main/java/org/owasp/esapi/errors/ValidationUploadException.java b/src/main/java/org/owasp/esapi/errors/ValidationUploadException.java new file mode 100644 index 000000000..825f15430 --- /dev/null +++ b/src/main/java/org/owasp/esapi/errors/ValidationUploadException.java @@ -0,0 +1,59 @@ +/** + * 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.errors; + +/** + * @author Jeff Williams (jeff.williams@aspectsecurity.com) + */ +public class ValidationUploadException extends ValidationException { + + /** The Constant serialVersionUID. */ + private static final long serialVersionUID = 1L; + + /** + * Instantiates a new validation exception. + */ + protected ValidationUploadException() { + // hidden + } + + /** + * Create a new ValidationException + * + * @param userMessage + * the message to display to users + * @param logMessage + * the message logged + */ + public ValidationUploadException(String userMessage, String logMessage) { + super(userMessage, logMessage); + } + + /** + * Create a new ValidationException + * + * @param userMessage + * the message to display to users + * @param logMessage + * the message logged + * @param cause + * the cause + */ + public ValidationUploadException(String userMessage, String logMessage, Throwable cause) { + super(userMessage, logMessage, cause); + } + +} diff --git a/src/main/java/org/owasp/esapi/errors/package.html b/src/main/java/org/owasp/esapi/errors/package.html new file mode 100644 index 000000000..4e061dd18 --- /dev/null +++ b/src/main/java/org/owasp/esapi/errors/package.html @@ -0,0 +1,17 @@ + + + + + + + +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. + + + diff --git a/src/main/java/org/owasp/esapi/filters/ClickjackFilter.java b/src/main/java/org/owasp/esapi/filters/ClickjackFilter.java new file mode 100644 index 000000000..e10a4e163 --- /dev/null +++ b/src/main/java/org/owasp/esapi/filters/ClickjackFilter.java @@ -0,0 +1,114 @@ +/** + * 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 February 6, 2009 + */ + +package org.owasp.esapi.filters; +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletResponse; + +/** + * The {@code ClickjackFilter} is configured as follows: + *
+ *
+ *     <filter>
+ *            <filter-name>ClickjackFilterDeny</filter-name>
+ *            <filter-class>org.owasp.filters.ClickjackFilter</filter-class>
+ *            <init-param>
+ *                <param-name>mode</param-name>
+ *                 <param-value>DENY</param-value>
+ *             </init-param>
+ *         </filter>
+ *
+ *         <filter>
+ *             <filter-name>ClickjackFilterSameOrigin</filter-name>
+ *             <filter-class>org.owasp.filters.ClickjackFilter</filter-class>
+ *             <init-param>
+ *                 <param-name>mode</param-name>
+ *                 <param-value>SAMEORIGIN</param-value>
+ *             </init-param>
+ *         </filter>
+ *
+ *        <!--  use the Deny version to prevent anyone, including yourself, from framing the page -->
+ *        <filter-mapping>
+ *            <filter-name>ClickjackFilterDeny</filter-name>
+ *            <url-pattern>/*</url-pattern>
+ *        </filter-mapping>
+ *
+ *         <!-- use the SameOrigin version to allow your application to frame, but nobody else
+ *         <filter-mapping>
+ *            <filter-name>ClickjackFilterSameOrigin</filter-name>
+ *             <url-pattern>/*</url-pattern>
+ *         </filter-mapping>
+ * 
+ * + * @see + * OWASP - Clickjacking Filter for JavaEE + * @see OWASP - Clickjacking Attack + * @see + * OWASP - Clickjacking Defense Cheat Sheet + */ +public class ClickjackFilter implements Filter +{ + + private String mode = "DENY"; + + /** + * Initialize "mode" parameter from web.xml. Valid values are "DENY" and "SAMEORIGIN". + * If you leave this parameter out, the default is to use the DENY mode. + * + * @param filterConfig A filter configuration object used by a servlet container + * to pass information to a filter during initialization. + */ + public void init(FilterConfig filterConfig) { + String configMode = filterConfig.getInitParameter("mode"); + if ( configMode != null && ( configMode.equals( "DENY" ) || configMode.equals( "SAMEORIGIN" ) ) ) { + mode = configMode; + } + } + + /** + * Add X-FRAME-OPTIONS response header to tell IE8 (and any other browsers who + * decide to implement) not to display this content in a frame. For details, please + * refer to + * @link http://blogs.msdn.com/sdl/archive/2009/02/05/clickjacking-defense-in-ie8.aspx + * + * @param request The request object. + * @param response The response object. + * @param chain Refers to the {@code FilterChain} object to pass control to the + * next {@code Filter}. + * @throws IOException + * @throws ServletException + */ + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException + { + HttpServletResponse res = (HttpServletResponse)response; + res.addHeader("X-FRAME-OPTIONS", mode ); + chain.doFilter(request, response); + } + + /** + * {@inheritDoc} + */ + public void destroy() { + } + +} diff --git a/src/main/java/org/owasp/esapi/filters/ESAPIFilter.java b/src/main/java/org/owasp/esapi/filters/ESAPIFilter.java new file mode 100644 index 000000000..be0417bcf --- /dev/null +++ b/src/main/java/org/owasp/esapi/filters/ESAPIFilter.java @@ -0,0 +1,162 @@ +/** + * 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.filters; + +import java.io.IOException; +import java.util.Arrays; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Logger; +import org.owasp.esapi.errors.AuthenticationException; + +/** + * + * @author jwilliams + */ +public class ESAPIFilter implements Filter { + + private final Logger logger = ESAPI.getLogger("ESAPIFilter"); + + private static final String[] obfuscate = { "password" }; + + private String loginPage = "WEB-INF/login.jsp"; + private String publicUnauthorizedLandingPage = "WEB-INF/index.jsp"; + + /** + * 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. + *

+ * Init parameters in web.xml for this filter: + *

    + *
  • resourceDirectory: sets ESAPI resource directory. No default.
  • + *
  • loginPage: login page for your application. Default is "WEB-INF/login.jsp".
  • + *
  • publicUnauthorizedLandingPage: page to forward unauthorized attempts + * to. Generally should be public, but must at least be available to all authenticated users. + * Default is "WEB-INF/index.jsp".
  • + *
+ *

+ * + * @param filterConfig + * configuration object + */ + public void init(FilterConfig filterConfig) { + String path = filterConfig.getInitParameter("resourceDirectory"); + if ( path != null ) { + ESAPI.securityConfiguration().setResourceDirectory( path ); + } + String paramLoginPage = filterConfig.getInitParameter("loginPage"); + if ( paramLoginPage != null ) { + loginPage = paramLoginPage; + } + String paramUnauthorizedPage = filterConfig.getInitParameter("publicUnauthorizedLandingPage"); + if ( paramUnauthorizedPage != null ) { + publicUnauthorizedLandingPage = paramUnauthorizedPage; + } + } + + /** + * 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. + * + * @param req + * Request object to be processed + * @param resp + * Response object + * @param chain + * current FilterChain + * @exception IOException + * if any occurs + */ + public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException { + HttpServletRequest request = (HttpServletRequest) req; + HttpServletResponse response = (HttpServletResponse) resp; + ESAPI.httpUtilities().setCurrentHTTP(request, response); + + try { + // figure out who the current user is + try { + ESAPI.authenticator().login(request, response); + } catch( AuthenticationException e ) { + ESAPI.authenticator().logout(); + request.setAttribute("message", "Authentication failed"); + RequestDispatcher dispatcher = request.getRequestDispatcher(loginPage); + dispatcher.forward(request, response); + return; + } + + // log this request, obfuscating any parameter named password + ESAPI.httpUtilities().logHTTPRequest(request, logger, Arrays.asList(obfuscate)); + + // check access to this URL + if ( !ESAPI.accessController().isAuthorizedForURL(request.getRequestURI()) ) { + request.setAttribute("message", "Unauthorized" ); + RequestDispatcher dispatcher = request.getRequestDispatcher(publicUnauthorizedLandingPage); + dispatcher.forward(request, response); + return; + } + + // check for CSRF attacks + // ESAPI.httpUtilities().checkCSRFToken(); + + // forward this request on to the web application + chain.doFilter(request, response); + + // set up response with content type + ESAPI.httpUtilities().setContentType( response ); + + // set no-cache headers on every response + // only do this if the entire site should not be cached + // otherwise you should do this strategically in your controller or actions + ESAPI.httpUtilities().setNoCacheHeaders( response ); + + } catch (Exception e) { + logger.error( Logger.SECURITY_FAILURE, "Error in ESAPI security filter: " + e.getMessage(), e ); + request.setAttribute("message", e.getMessage() ); + + } finally { + // VERY IMPORTANT + // clear out the ThreadLocal variables in the authenticator + // some containers could possibly reuse this thread without clearing the User + ESAPI.clearCurrent(); + } + } + + /** + * 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. + */ + public void destroy() { + // finalize + } + +} diff --git a/src/main/java/org/owasp/esapi/filters/RequestRateThrottleFilter.java b/src/main/java/org/owasp/esapi/filters/RequestRateThrottleFilter.java new file mode 100644 index 000000000..47774b895 --- /dev/null +++ b/src/main/java/org/owasp/esapi/filters/RequestRateThrottleFilter.java @@ -0,0 +1,110 @@ +/** + * 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.filters; + +import org.owasp.esapi.ESAPI; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import java.io.IOException; +import java.util.Date; +import java.util.List; +import java.util.LinkedList; + +/** + * A simple servlet filter that limits the request rate to a certain threshold of requests per second. + * The default rate is 5 hits in 10 seconds. This can be overridden in the web.xml file by adding + * parameters named "hits" and "period" with the desired values. When the rate is exceeded, a short + * string is written to the response output stream and the chain method is not invoked. Otherwise, + * processing proceeds as normal. + */ +public class RequestRateThrottleFilter implements Filter +{ + + private int hits = 5; + + private int period = 10; + + private static final String HITS = "hits"; + + private static final String PERIOD = "period"; + + /** + * 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. + * + * @param filterConfig + * configuration object + */ + public void init(FilterConfig filterConfig) + { + hits = filterConfig.getInitParameter(HITS) == null ? 5 : Integer.parseInt(filterConfig.getInitParameter(HITS)); + period = filterConfig.getInitParameter(PERIOD) == null ? 10 : Integer.parseInt(filterConfig.getInitParameter(PERIOD)); + } + + /** + * Checks to see if the current session has exceeded the allowed number + * of requests in the specified time period. If the threshold has been + * exceeded, then a short error message is written to the output stream and + * no further processing is done on the request. Otherwise, the request is + * processed as normal. + * @param request + * @param response + * @param chain + * @throws IOException + * @throws ServletException + */ + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException + { + HttpServletRequest httpRequest = (HttpServletRequest) request; + HttpSession session = httpRequest.getSession(true); + + synchronized( session.getId().intern() ) { + List times = ESAPI.httpUtilities().getSessionAttribute("times"); + if (times == null) { + times = new LinkedList(); + session.setAttribute("times", times); + } + Long newest = System.currentTimeMillis(); + times.add(newest); + if (times.size() > hits) { + Long oldest = times.remove(0); + long elapsed = newest - oldest; + if (elapsed < period * 1000) { + response.getWriter().println("Request rate too high"); + return; + } + } + } + chain.doFilter(request, response); + } + + /** + * 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. + */ + public void destroy() + { + // finalize + } + +} diff --git a/src/main/java/org/owasp/esapi/filters/SecurityWrapper.java b/src/main/java/org/owasp/esapi/filters/SecurityWrapper.java new file mode 100644 index 000000000..cea61ba65 --- /dev/null +++ b/src/main/java/org/owasp/esapi/filters/SecurityWrapper.java @@ -0,0 +1,136 @@ +/** + * 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.filters; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Logger; +import org.owasp.esapi.StringUtilities; + + +/** + * 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. + *

+ * Example Configuration #1 (Default Configuration allows /WEB-INF): + *

+ * <filter>
+ *    <filter-name>SecurityWrapperDefault</filter-name>
+ *    <filter-class>org.owasp.filters.SecurityWrapper</filter-class>
+ * </filter>
+ * 
+ *

+ * Example Configuration #2 (Allows /servlet) + *

+ * <filter>
+ *    <filter-name>SecurityWrapperForServlet</filter-name>
+ *    <filter-class>org.owasp.filters.SecurityWrapper</filter-class>
+ *    <init-param>
+ *       <param-name>allowableResourceRoot</param-name>
+ *       <param-value>/servlet</param-value>
+ *    </init-param>
+ * </filter>
+ * 
+ * + * @author Chris Schmidt (chrisisbeef@gmail.com) + */ +public class SecurityWrapper implements Filter { + + private final Logger logger = ESAPI.getLogger("SecurityWrapper"); + + /** + * This is the root path of what resources this filter will allow a RequestDispatcher to be dispatched to. This + * defaults to WEB-INF as best practice dictates that dispatched requests should be done to resources that are + * not browsable and everything behind WEB-INF is protected by the container. However, it is possible and sometimes + * required to dispatch requests to places outside of the WEB-INF path (such as to another servlet). + * + * See http://code.google.com/p/owasp-esapi-java/issues/detail?id=70 + * and https://lists.owasp.org/pipermail/owasp-esapi/2009-December/001672.html + * for details. + */ + private String allowableResourcesRoot = "WEB-INF"; + + /** + * + * @param request + * @param response + * @param chain + * @throws java.io.IOException + * @throws javax.servlet.ServletException + */ + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + if (!(request instanceof HttpServletRequest)) { + chain.doFilter(request, response); + return; + } + + try { + HttpServletRequest hrequest = (HttpServletRequest)request; + HttpServletResponse hresponse = (HttpServletResponse)response; + + SecurityWrapperRequest secureRequest = new SecurityWrapperRequest(hrequest); + SecurityWrapperResponse secureResponse = new SecurityWrapperResponse(hresponse); + + // Set the configuration on the wrapped request + secureRequest.setAllowableContentRoot(allowableResourcesRoot); + + ESAPI.httpUtilities().setCurrentHTTP(secureRequest, secureResponse); + + chain.doFilter(ESAPI.currentRequest(), ESAPI.currentResponse()); + } catch (Exception e) { + logger.error( Logger.SECURITY_FAILURE, "Error in SecurityWrapper: " + e.getMessage(), e ); + request.setAttribute("message", e.getMessage() ); + } finally { + // VERY IMPORTANT + // clear out the ThreadLocal variables in the authenticator + // some containers could possibly reuse this thread without clearing the User + // Issue 70 - http://code.google.com/p/owasp-esapi-java/issues/detail?id=70 + ESAPI.httpUtilities().clearCurrent(); + } + } + + /** + * + */ + public void destroy() { + // no special action + } + + /** + * + * @param filterConfig + * @throws javax.servlet.ServletException + */ + public void init(FilterConfig filterConfig) throws ServletException { + this.allowableResourcesRoot = StringUtilities.replaceNull( filterConfig.getInitParameter( "allowableResourcesRoot" ), allowableResourcesRoot ); + } + +} diff --git a/src/main/java/org/owasp/esapi/filters/SecurityWrapperRequest.java b/src/main/java/org/owasp/esapi/filters/SecurityWrapperRequest.java new file mode 100644 index 000000000..71c74c652 --- /dev/null +++ b/src/main/java/org/owasp/esapi/filters/SecurityWrapperRequest.java @@ -0,0 +1,854 @@ +/** + * 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.filters; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.security.Principal; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Vector; + +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletInputStream; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Logger; +import org.owasp.esapi.SecurityConfiguration; +import org.owasp.esapi.errors.AccessControlException; +import org.owasp.esapi.errors.ValidationException; + +// TODO: Parameterize these various lengths in calls to ESAPI.validator().getValidInput() +// so that they can be placed in ESAPI.properties file (or other property file, +// such as Validator.properties) rather than being hard-coded. This is desirable +// because many of the values are well less than the commonly accepted maximum +// values. + +/** + * 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. + */ +public class SecurityWrapperRequest extends HttpServletRequestWrapper implements HttpServletRequest { + + private final Logger logger = ESAPI.getLogger("SecurityWrapperRequest"); + + private String allowableContentRoot = "WEB-INF"; + + /** + * Construct a safe request that overrides the default request methods with + * safer versions. + * + * @param request The {@code HttpServletRequest} we are wrapping. + */ + public SecurityWrapperRequest(HttpServletRequest request) { + super( request ); + } + + private HttpServletRequest getHttpServletRequest() { + return (HttpServletRequest)super.getRequest(); + } + + /** + * Same as HttpServletRequest, no security changes required. + * @param name The attribute name + * @return The attribute value + */ + public Object getAttribute(String name) { + return getHttpServletRequest().getAttribute(name); + } + + /** + * Same as HttpServletRequest, no security changes required. + * @return An {@code Enumeration} of attribute names. + */ + public Enumeration getAttributeNames() { + return getHttpServletRequest().getAttributeNames(); + } + + /** + * Same as HttpServletRequest, no security changes required. + * @return The authentication type + */ + public String getAuthType() { + return getHttpServletRequest().getAuthType(); + } + + /** + * Same as HttpServletRequest, no security changes required. + * @return The character-encoding for this {@code HttpServletRequest} + */ + public String getCharacterEncoding() { + return getHttpServletRequest().getCharacterEncoding(); + } + + /** + * Same as HttpServletRequest, no security changes required. + * @return The content-length for this {@code HttpServletRequest} + */ + public int getContentLength() { + return getHttpServletRequest().getContentLength(); + } + + /** + * Same as HttpServletRequest, no security changes required. + * @return The content-type for this {@code HttpServletRequest} + */ + public String getContentType() { + return getHttpServletRequest().getContentType(); + } + + /** + * Returns the context path from the HttpServletRequest after canonicalizing + * and filtering out any dangerous characters. + * @return The context path for this {@code HttpServletRequest} + */ + public String getContextPath() { + String path = getHttpServletRequest().getContextPath(); + SecurityConfiguration sc = ESAPI.securityConfiguration(); + //Return empty String for the ROOT context + if (path == null || "".equals(path.trim())) return ""; + + String clean = ""; + try { + clean = ESAPI.validator().getValidInput("HTTP context path: " + path, path, "HTTPContextPath", sc.getIntProp("HttpUtilities.contextPathLength"), false); + } catch (ValidationException e) { + // already logged + } + return clean; + } + + /** + * Returns the array of Cookies from the HttpServletRequest after + * canonicalizing and filtering out any dangerous characters. + * @return An array of {@code Cookie}s for this {@code HttpServletRequest} + */ + public Cookie[] getCookies() { + Cookie[] cookies = getHttpServletRequest().getCookies(); + if (cookies == null) return new Cookie[0]; + SecurityConfiguration sc = ESAPI.securityConfiguration(); + List newCookies = new ArrayList(); + for (Cookie c : cookies) { + // build a new clean cookie + try { + // get data from original cookie + String name = ESAPI.validator().getValidInput("Cookie name: " + c.getName(), c.getName(), "HTTPCookieName", sc.getIntProp("HttpUtilities.MaxHeaderNameSize"), false); + String value = ESAPI.validator().getValidInput("Cookie value: " + c.getValue(), c.getValue(), "HTTPCookieValue", sc.getIntProp("HttpUtilities.MaxHeaderValueSize"), true); + int maxAge = c.getMaxAge(); + String domain = c.getDomain(); + String path = c.getPath(); + + Cookie n = new Cookie(name, value); + n.setMaxAge(maxAge); + + if (domain != null) { + // kww TODO: HTTPHeaderValue seems way too liberal of a regex for cookie domain + // as it allows invalid characters for a domain name. Maybe create a new custom + // HTTPCookieDomain regex??? + n.setDomain(ESAPI.validator().getValidInput("Cookie domain: " + domain, domain, "HTTPHeaderValue", sc.getIntProp("HttpUtilities.MaxHeaderValueSize"), false)); + } + if (path != null) { + // kww TODO: OPEN ISSUE: Would not HTTPServletPath make more sense here??? + n.setPath(ESAPI.validator().getValidInput("Cookie path: " + path, path, "HTTPHeaderValue", sc.getIntProp("HttpUtilities.MaxHeaderValueSize"), false)); + } + newCookies.add(n); + } catch (ValidationException e) { + logger.warning(Logger.SECURITY_FAILURE, "Skipping bad cookie: " + c.getName() + "=" + c.getValue(), e ); + } + } + return newCookies.toArray(new Cookie[newCookies.size()]); + } + + /** + * Same as HttpServletRequest, no security changes required. + * @param name Specifies the name of the HTTP request header; e.g., + * {@code If-Modified-Since}. + * @return a long value representing the date specified in the header + * expressed as the number of milliseconds since {@code January 1, 1970 GMT}, + * or {@code -1} if the named header was not included with the request. + */ + public long getDateHeader(String name) { + return getHttpServletRequest().getDateHeader(name); + } + + /** + * Returns the named header from the HttpServletRequest after canonicalizing + * and filtering out any dangerous characters. + * @param name The name of an HTTP request header + * @return The specified header value is returned. + */ + public String getHeader(String name) { + String value = getHttpServletRequest().getHeader(name); + String clean = ""; + SecurityConfiguration sc = ESAPI.securityConfiguration(); + try { + clean = ESAPI.validator().getValidInput("HTTP header value: " + value, value, "HTTPHeaderValue", sc.getIntProp("HttpUtilities.MaxHeaderValueSize"), true); + } catch (ValidationException e) { + // already logged + } + return clean; + } + + /** + * Returns the enumeration of header names from the HttpServletRequest after + * canonicalizing and filtering out any dangerous characters. + * @return An {@code Enumeration} of header names associated with this request. + */ + public Enumeration getHeaderNames() { + Vector v = new Vector(); + Enumeration en = getHttpServletRequest().getHeaderNames(); + SecurityConfiguration sc = ESAPI.securityConfiguration(); + while (en.hasMoreElements()) { + try { + String name = (String) en.nextElement(); + String clean = ESAPI.validator().getValidInput("HTTP header name: " + name, name, "HTTPHeaderName", sc.getIntProp("HttpUtilities.MaxHeaderNameSize"), true); + v.add(clean); + } catch (ValidationException e) { + // already logged + } + } + return v.elements(); + } + + /** + * Returns the enumeration of headers from the HttpServletRequest after + * canonicalizing and filtering out any dangerous characters. + * @param name The name of an HTTP request header. + * @return An {@code Enumeration} of headers from the request after + * canonicalizing and filtering has been performed. + */ + public Enumeration getHeaders(String name) { + Vector v = new Vector(); + Enumeration en = getHttpServletRequest().getHeaders(name); + SecurityConfiguration sc = ESAPI.securityConfiguration(); + while (en.hasMoreElements()) { + try { + String value = (String) en.nextElement(); + String clean = ESAPI.validator().getValidInput("HTTP header value (" + name + "): " + value, value, "HTTPHeaderValue", sc.getIntProp("HttpUtilities.httpQueryParamValueLength"), true); + v.add(clean); + } catch (ValidationException e) { + // already logged + } + } + return v.elements(); + } + + /** + * 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. + * @return The {@code ServletInputStream} associated with this + * {@code HttpServletRequest}. + * @throws IOException Thrown if an input exception is thrown, such as the + * remote peer closing the connection. + */ + public ServletInputStream getInputStream() throws IOException { + return getHttpServletRequest().getInputStream(); + } + + /** + * Same as HttpServletRequest, no security changes required. + * @param name The name of an HTTP request header. + * @return Returns the value of the specified request header as an {@code int}. + */ + public int getIntHeader(String name) { + return getHttpServletRequest().getIntHeader(name); + } + + /** + * Same as HttpServletRequest, no security changes required. + * @return A {@code String} containing the IP address on which the + * request was received. + */ + public String getLocalAddr() { + return getHttpServletRequest().getLocalAddr(); + } + + /** + * Same as HttpServletRequest, no security changes required. + * @return The preferred {@code Locale} for the client. + */ + public Locale getLocale() { + return getHttpServletRequest().getLocale(); + } + + /** + * Same as HttpServletRequest, no security changes required. + * @return An {@code Enumeration} of preferred {@code Locale} + * objects for the client. + */ + public Enumeration getLocales() { + return getHttpServletRequest().getLocales(); + } + + /** + * Same as HttpServletRequest, no security changes required. + * @return A {@code String} containing the host name of the IP on which + * the request was received. + */ + public String getLocalName() { + return getHttpServletRequest().getLocalName(); + } + + /** + * Same as HttpServletRequest, no security changes required. + * @return Returns the Internet Protocol (IP) port number of the interface + * on which the request was received. + */ + public int getLocalPort() { + return getHttpServletRequest().getLocalPort(); + } + + /** + * Same as HttpServletRequest, no security changes required. + * @return Returns the name of the HTTP method with which this request was made. + */ + public String getMethod() { + return getHttpServletRequest().getMethod(); + } + + /** + * Returns the named parameter from the HttpServletRequest after + * canonicalizing and filtering out any dangerous characters. + * @param name The parameter name for the request + * @return The "scrubbed" parameter value. + */ + public String getParameter(String name) { + return getParameter(name, true); + } + + /** + * Returns the named parameter from the HttpServletRequest after + * canonicalizing and filtering out any dangerous characters. + * @param name The parameter name for the request + * @param allowNull Whether null values are allowed + * @return The "scrubbed" parameter value. + */ + public String getParameter(String name, boolean allowNull) { + SecurityConfiguration sc = ESAPI.securityConfiguration(); + return getParameter(name, allowNull, sc.getIntProp("HttpUtilities.httpQueryParamValueLength"), "HTTPParameterValue"); + } + + /** + * Returns the named parameter from the HttpServletRequest after + * canonicalizing and filtering out any dangerous characters. + * @param name The parameter name for the request + * @param allowNull Whether null values are allowed + * @param maxLength The maximum length allowed + * @return The "scrubbed" parameter value. + */ + public String getParameter(String name, boolean allowNull, int maxLength) { + return getParameter(name,allowNull,maxLength,"HTTPParameterValue"); + } + + /** + * Returns the named parameter from the HttpServletRequest after + * canonicalizing and filtering out any dangerous characters. + * @param name The parameter name for the request + * @param allowNull Whether null values are allowed + * @param maxLength The maximum length allowed + * @param regexName The name of the regex mapped from ESAPI.properties + * @return The "scrubbed" parameter value. + */ + public String getParameter(String name, boolean allowNull, int maxLength, String regexName) { + String orig = getHttpServletRequest().getParameter(name); + String clean = null; + try { + clean = ESAPI.validator().getValidInput("HTTP parameter name: " + name, orig, regexName, maxLength, allowNull); + } catch (ValidationException e) { + // already logged + } + return clean; + } + + /** + * Returns the parameter map from the HttpServletRequest after + * canonicalizing and filtering out any dangerous characters. + * @return A {@code Map} containing scrubbed parameter names / value pairs. + */ + public Map getParameterMap() { + @SuppressWarnings({"unchecked"}) + Map map = getHttpServletRequest().getParameterMap(); + Map cleanMap = new HashMap(); + for (Object o : map.entrySet()) { + try { + Map.Entry e = (Map.Entry) o; + String name = (String) e.getKey(); + SecurityConfiguration sc = ESAPI.securityConfiguration(); + String cleanName = ESAPI.validator().getValidInput("HTTP parameter name: " + name, name, "HTTPParameterName", sc.getIntProp("HttpUtilities.httpQueryParamNameLength"), true); + + String[] value = (String[]) e.getValue(); + String[] cleanValues = new String[value.length]; + for (int j = 0; j < value.length; j++) { + String cleanValue = ESAPI.validator().getValidInput("HTTP parameter value: " + value[j], value[j], "HTTPParameterValue", sc.getIntProp("HttpUtilities.httpQueryParamValueLength"), true); + cleanValues[j] = cleanValue; + } + cleanMap.put(cleanName, cleanValues); + } catch (ValidationException e) { + // already logged + } + } + return cleanMap; + } + + /** + * Returns the enumeration of parameter names from the HttpServletRequest + * after canonicalizing and filtering out any dangerous characters. + * @return An {@code Enumeration} of properly "scrubbed" parameter names. + */ + public Enumeration getParameterNames() { + Vector v = new Vector(); + Enumeration en = getHttpServletRequest().getParameterNames(); + while (en.hasMoreElements()) { + try { + SecurityConfiguration sc = ESAPI.securityConfiguration(); + String name = (String) en.nextElement(); + String clean = ESAPI.validator().getValidInput("HTTP parameter name: " + name, name, "HTTPParameterName", sc.getIntProp("HttpUtilities.httpQueryParamNameLength"), true); + v.add(clean); + } catch (ValidationException e) { + // already logged + } + } + return v.elements(); + } + + /** + * Returns the array of matching parameter values from the + * HttpServletRequest after canonicalizing and filtering out any dangerous + * characters. + * @param name The parameter name + * @return An array of matching "scrubbed" parameter values or + * null if the parameter does not exist. + */ + public String[] getParameterValues(String name) { + String[] values = getHttpServletRequest().getParameterValues(name); + List newValues; + + if(values == null) + return null; + newValues = new ArrayList(); + SecurityConfiguration sc = ESAPI.securityConfiguration(); + for (String value : values) { + try { + String cleanValue = ESAPI.validator().getValidInput("HTTP parameter value: " + value, value, "HTTPParameterValue", sc.getIntProp("HttpUtilities.URILENGTH"), true); + newValues.add(cleanValue); + } catch (ValidationException e) { + logger.warning(Logger.SECURITY_FAILURE, "Skipping bad parameter"); + } + } + return newValues.toArray(new String[newValues.size()]); + } + + /** + * Returns the path info from the HttpServletRequest after canonicalizing + * and filtering out any dangerous characters. + * @return Returns any extra path information, appropriately scrubbed, + * associated with the URL the client sent when it made this request. + */ + public String getPathInfo() { + String path = getHttpServletRequest().getPathInfo(); + if (path == null) return null; + String clean = ""; + SecurityConfiguration sc = ESAPI.securityConfiguration(); + try { + clean = ESAPI.validator().getValidInput("HTTP path: " + path, path, "HTTPPath", sc.getIntProp("HttpUtilities.HTTPPATHLENGTH"), true); + } catch (ValidationException e) { + // already logged + } + return clean; + } + + /** + * Same as HttpServletRequest, no security changes required. + * @return Returns any extra path information, appropriate scrubbed, + * after the servlet name but before the query string, and + * translates it to a real path. + */ + public String getPathTranslated() { + return getHttpServletRequest().getPathTranslated(); + } + + /** + * Same as HttpServletRequest, no security changes required. + * @return Returns the name and version of the protocol the request uses in + * the form protocol/majorVersion.minorVersion, for example, HTTP/1.1. + */ + public String getProtocol() { + return getHttpServletRequest().getProtocol(); + } + + /** + * Returns the query string from the HttpServletRequest after canonicalizing + * and filtering out any dangerous characters. + * @return The scrubbed query string is returned. + */ + public String getQueryString() { + String query = getHttpServletRequest().getQueryString(); + String clean = ""; + SecurityConfiguration sc = ESAPI.securityConfiguration(); + try { + clean = ESAPI.validator().getValidInput("HTTP query string: " + query, query, "HTTPQueryString", sc.getIntProp("HttpUtilities.URILENGTH"), true); + } catch (ValidationException e) { + // already logged + } + return clean; + } + + /** + * 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. + * @return aA {@code BufferedReader} containing the body of the request. + * @throws IOException If an input error occurred while reading the request + * body (e.g., premature EOF). + */ + public BufferedReader getReader() throws IOException { + return getHttpServletRequest().getReader(); + } + + // CHECKME: Should this be deprecated since ServletRequest.getRealPath(String) + // is deprecated? Should use ServletContext.getRealPath(String) instead. + /** + * Same as HttpServletRequest, no security changes required. + * @param path A virtual path on a web or application server; e.g., "/index.htm". + * @return Returns a String containing the real path for a given virtual path. + * @deprecated in servlet spec 2.1. Use {@link javax.servlet.ServletContext#getRealPath(String)} instead. + */ + @SuppressWarnings({"deprecation"}) + @Deprecated + public String getRealPath(String path) { + return getHttpServletRequest().getRealPath(path); + } + + /** + * Same as HttpServletRequest, no security changes required. + * @return Returns the IP address of the client or last proxy that sent the request. + */ + public String getRemoteAddr() { + return getHttpServletRequest().getRemoteAddr(); + } + + /** + * Same as HttpServletRequest, no security changes required. + * @return The remote host + */ + public String getRemoteHost() { + return getHttpServletRequest().getRemoteHost(); + } + + /** + * Same as HttpServletRequest, no security changes required. + * @return The remote port + */ + public int getRemotePort() { + return getHttpServletRequest().getRemotePort(); + } + + /** + * Returns the name of the ESAPI user associated with this getHttpServletRequest(). + * @return Returns the fully qualified name of the client or the last proxy + * that sent the request + */ + public String getRemoteUser() { + return ESAPI.authenticator().getCurrentUser().getAccountName(); + } + + /** + * Checks to make sure the path to forward to is within the WEB-INF + * directory and then returns the dispatcher. Otherwise returns null. + * @param path The path to create a request dispatcher for + * @return A {@code RequestDispatcher} object that acts as a wrapper for the + * resource at the specified path, or null if the servlet container + * cannot return a {@code RequestDispatcher}. + */ + public RequestDispatcher getRequestDispatcher(String path) { + if (path.startsWith(allowableContentRoot)) { + return getHttpServletRequest().getRequestDispatcher(path); + } + return null; + } + + /** + * 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. + * @return The requested Session ID + */ + public String getRequestedSessionId() { + String id = getHttpServletRequest().getRequestedSessionId(); + String clean = ""; + SecurityConfiguration sc = ESAPI.securityConfiguration(); + try { + clean = ESAPI.validator().getValidInput("Requested cookie: " + id, id, "HTTPJSESSIONID", sc.getIntProp("HttpUtilities.HTTPJSESSIONIDLENGTH"), false); + } catch (ValidationException e) { + // already logged + } + return clean; + } + + /** + * Returns the URI from the HttpServletRequest after canonicalizing and + * filtering out any dangerous characters. + * @return The current request URI + */ + public String getRequestURI() { + String uri = getHttpServletRequest().getRequestURI(); + String clean = ""; + SecurityConfiguration sc = ESAPI.securityConfiguration(); + try { + clean = ESAPI.validator().getValidInput("HTTP URI: " + uri, uri, "HTTPURI", sc.getIntProp("HttpUtilities.URILENGTH"), false); + } catch (ValidationException e) { + // already logged + } + return clean; + } + + /** + * Returns the URL from the HttpServletRequest after canonicalizing and + * filtering out any dangerous characters. + * @return The current request URL + */ + public StringBuffer getRequestURL() { + String url = getHttpServletRequest().getRequestURL().toString(); + String clean = ""; + SecurityConfiguration sc = ESAPI.securityConfiguration(); + try { + clean = ESAPI.validator().getValidInput("HTTP URL: " + url, url, "HTTPURL", sc.getIntProp("HttpUtilities.URILENGTH"), false); + } catch (ValidationException e) { + // already logged + } + return new StringBuffer(clean); + } + + /** + * Returns the scheme from the HttpServletRequest after canonicalizing and + * filtering out any dangerous characters. + * @return The scheme of the current request + */ + public String getScheme() { + String scheme = getHttpServletRequest().getScheme(); + String clean = ""; + SecurityConfiguration sc = ESAPI.securityConfiguration(); + try { + clean = ESAPI.validator().getValidInput("HTTP scheme: " + scheme, scheme, "HTTPScheme", sc.getIntProp("HttpUtilities.HTTPSCHEMELENGTH"), false); + } catch (ValidationException e) { + // already logged + } + return clean; + } + + /** + * Returns the server name (host header) from the HttpServletRequest after + * canonicalizing and filtering out any dangerous characters. + * @return The local server name + */ + public String getServerName() { + String name = getHttpServletRequest().getServerName(); + String clean = ""; + SecurityConfiguration sc = ESAPI.securityConfiguration(); + try { + clean = ESAPI.validator().getValidInput("HTTP server name: " + name, name, "HTTPServerName", sc.getIntProp("HttpUtilities.HTTPHOSTLENGTH"), false); + } catch (ValidationException e) { + // already logged + } + return clean; + } + + /** + * Returns the server port (after the : in the host header) from the + * HttpServletRequest after parsing and checking the range 0-65536. + * @return The local server port + */ + public int getServerPort() { + int port = getHttpServletRequest().getServerPort(); + if ( port < 0 || port > 0xFFFF ) { + logger.warning( Logger.SECURITY_FAILURE, "HTTP server port out of range: " + port ); + port = 0; + } + return port; + } + + + /** + * Returns the server path from the HttpServletRequest after canonicalizing + * and filtering out any dangerous characters. + * @return The servlet path + */ + public String getServletPath() { + String path = getHttpServletRequest().getServletPath(); + String clean = ""; + SecurityConfiguration sc = ESAPI.securityConfiguration(); + try { + clean = ESAPI.validator().getValidInput("HTTP servlet path: " + path, path, "HTTPServletPath", sc.getIntProp("HttpUtilities.HTTPSERVLETPATHLENGTH"), false); + } catch (ValidationException e) { + // already logged + } + return clean; + } + + /** + * Returns a session, creating it if necessary, and sets the HttpOnly flag + * on the Session ID cookie. The 'secure' flag is also set if the property + * {@code HttpUtilities.ForceSecureCookies} is set to {@code true} in the ESAPI.properties file. + * @return The current session + */ + public HttpSession getSession() { + return getSession(true); + } + + /** + * Returns the current session associated with this request or, if there is no current session and + * {@code create} is {@code true}, returns a new session and sets the HttpOnly flag on the session ID cookie. + * The 'secure' flag is also set if the property {@code HttpUtilities.ForceSecureCookies} is set to + * {@code true} in the ESAPI.properties file. + * @param create If set to {@code true}, create a new session if one doesn't exist, otherwise return {@code null} + * @return The current session + */ + public HttpSession getSession(boolean create) { + HttpSession session = getHttpServletRequest().getSession(create); + + if (session == null) { + return null; + } + + SecurityConfiguration sc = ESAPI.securityConfiguration(); + + // send a new cookie header with HttpOnly on first and second responses + if ( sc.getBooleanProp("HttpUtilities.ForceHttpOnlySession") ) { + if (session.getAttribute("HTTP_ONLY") == null) { + session.setAttribute("HTTP_ONLY", "set"); + Cookie cookie = new Cookie( sc.getStringProp("HttpUtilities.HttpSessionIdName"), session.getId() ); + cookie.setMaxAge(-1); // session cookie + cookie.setPath( getHttpServletRequest().getContextPath() ); + cookie.setSecure( sc.getBooleanProp("HttpUtilities.ForceSecureCookies") ); + HttpServletResponse response = ESAPI.currentResponse(); + if (response != null) { + ESAPI.currentResponse().addCookie(cookie); + } + } + } + return session; + } + + /** + * Returns the ESAPI User associated with this getHttpServletRequest(). + * @return The ESAPI User + */ + public Principal getUserPrincipal() { + return ESAPI.authenticator().getCurrentUser(); + } + + /** + * Same as HttpServletRequest, no security changes required. + * @return if requested session id is from a cookie + */ + public boolean isRequestedSessionIdFromCookie() { + return getHttpServletRequest().isRequestedSessionIdFromCookie(); + } + + /** + * Same as HttpServletRequest, no security changes required. + * @return Whether the requested session id is from the URL + * @deprecated in servlet spec 2.1. Use {@link #isRequestedSessionIdFromURL()} instead. + */ + @SuppressWarnings({"deprecation"}) + @Deprecated + public boolean isRequestedSessionIdFromUrl() { + return getHttpServletRequest().isRequestedSessionIdFromUrl(); + } + + /** + * Same as HttpServletRequest, no security changes required. + * @return Whether the requested session id is from the URL + */ + public boolean isRequestedSessionIdFromURL() { + return getHttpServletRequest().isRequestedSessionIdFromURL(); + } + + /** + * Same as HttpServletRequest, no security changes required. + * @return Whether the requested session id is valid + */ + public boolean isRequestedSessionIdValid() { + return getHttpServletRequest().isRequestedSessionIdValid(); + } + + /** + * Same as HttpServletRequest, no security changes required. + * @return Whether the current request is secure + */ + public boolean isSecure() { + try { + ESAPI.httpUtilities().assertSecureChannel(); + } catch (AccessControlException e) { + return false; + } + return true; + } + + /** + * Returns true if the ESAPI User associated with this request has the + * specified role. + * @param role The role to check + * @return Whether the current user is in the passed role + */ + public boolean isUserInRole(String role) { + return ESAPI.authenticator().getCurrentUser().isInRole(role); + } + + /** + * Same as HttpServletRequest, no security changes required. + * @param name The attribute name + */ + public void removeAttribute(String name) { + getHttpServletRequest().removeAttribute(name); + } + + /** + * Same as HttpServletRequest, no security changes required. + * @param name The attribute name + * @param o The attribute value + */ + public void setAttribute(String name, Object o) { + getHttpServletRequest().setAttribute(name, o); + } + + /** + * Sets the character encoding scheme to the ESAPI configured encoding scheme. + * @param enc The encoding scheme + * @throws UnsupportedEncodingException + */ + public void setCharacterEncoding(String enc) throws UnsupportedEncodingException { + getHttpServletRequest().setCharacterEncoding(ESAPI.securityConfiguration().getStringProp("HttpUtilities.CharacterEncoding")); + } + + public String getAllowableContentRoot() { + return allowableContentRoot; + } + + public void setAllowableContentRoot(String allowableContentRoot) { + this.allowableContentRoot = allowableContentRoot.startsWith( "/" ) ? allowableContentRoot : "/" + allowableContentRoot; + } +} diff --git a/src/main/java/org/owasp/esapi/filters/SecurityWrapperResponse.java b/src/main/java/org/owasp/esapi/filters/SecurityWrapperResponse.java new file mode 100644 index 000000000..f05682cba --- /dev/null +++ b/src/main/java/org/owasp/esapi/filters/SecurityWrapperResponse.java @@ -0,0 +1,592 @@ +/** + * 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.filters; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Locale; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpServletResponseWrapper; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Logger; +import org.owasp.esapi.SecurityConfiguration; +import org.owasp.esapi.StringUtilities; +import org.owasp.esapi.ValidationErrorList; +import org.owasp.esapi.errors.IntrusionException; +import org.owasp.esapi.errors.ValidationException; + +/** + * This response wrapper simply overrides unsafe methods in the + * HttpServletResponse API with safe versions. + */ +public class SecurityWrapperResponse extends HttpServletResponseWrapper implements HttpServletResponse { + + private final Logger logger = ESAPI.getLogger("SecurityWrapperResponse"); + + // modes are "log", "skip", "sanitize", "throw" + // TODO: move this to SecurityConfiguration + private String mode = "log"; + + /** + * Construct a safe response that overrides the default response methods + * with safer versions. Default is 'log' mode. + * + * @param response + */ + public SecurityWrapperResponse(HttpServletResponse response) { + super( response ); + } + + /** + * Construct a safe response that overrides the default response methods + * with safer versions. + * + * @param response + * @param mode The mode for this wrapper. Legal modes are "log", "skip", "sanitize", "throw". + */ + public SecurityWrapperResponse(HttpServletResponse response, String mode) { + super( response ); + this.mode = mode; + } + + + private HttpServletResponse getHttpServletResponse() { + return (HttpServletResponse)super.getResponse(); + } + + /** + * 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. This implementation uses a + * custom "set-cookie" header instead of using Java's cookie interface which + * doesn't allow the use of HttpOnly. + * @param cookie + */ + public void addCookie(Cookie cookie) { + String name = cookie.getName(); + String value = cookie.getValue(); + int maxAge = cookie.getMaxAge(); + String domain = cookie.getDomain(); + String path = cookie.getPath(); + boolean secure = cookie.getSecure(); + SecurityConfiguration sc = ESAPI.securityConfiguration(); + + // validate the name and value + ValidationErrorList errors = new ValidationErrorList(); + String cookieName = ESAPI.validator().getValidInput("cookie name", name, "HTTPCookieName", sc.getIntProp("HttpUtilities.MaxHeaderNameSize"), false, errors); + String cookieValue = ESAPI.validator().getValidInput("cookie value", value, "HTTPCookieValue", sc.getIntProp("HttpUtilities.MaxHeaderValueSize"), false, errors); + + // if there are no errors, then just set a cookie header + if (errors.size() == 0) { + String header = createCookieHeader(name, value, maxAge, domain, path, secure); + this.addHeader("Set-Cookie", header); + return; + } + + // if there was an error + if (mode.equals("skip")) { + logger.warning(Logger.SECURITY_FAILURE, "Attempt to add unsafe data to cookie (skip mode). Skipping cookie and continuing."); + return; + } + + // add the original cookie to the response and continue + if (mode.equals("log")) { + logger.warning(Logger.SECURITY_FAILURE, "Attempt to add unsafe data to cookie (log mode). Adding unsafe cookie anyway and continuing."); + getHttpServletResponse().addCookie(cookie); + return; + } + + // create a sanitized cookie header and continue + if (mode.equals("sanitize")) { + logger.warning(Logger.SECURITY_FAILURE, "Attempt to add unsafe data to cookie (sanitize mode). Sanitizing cookie and continuing."); + String header = createCookieHeader(cookieName, cookieValue, maxAge, domain, path, secure); + this.addHeader("Set-Cookie", header); + return; + } + + // throw an exception if necessary or add original cookie header + throw new IntrusionException("Security error", "Attempt to add unsafe data to cookie (throw mode)"); + } + + private String createCookieHeader(String name, String value, int maxAge, String domain, String path, boolean secure) { + // create the special cookie header instead of creating a Java cookie + // Set-Cookie:=[; =][; expires=][; + // domain=][; path=][; secure][;HttpOnly + String header = name + "=" + value; + if (maxAge >= 0) { + header += "; Max-Age=" + maxAge; + } + if (domain != null) { + header += "; Domain=" + domain; + } + if (path != null) { + header += "; Path=" + path; + } + if ( secure || ESAPI.securityConfiguration().getBooleanProp("HttpUtilities.ForceSecureCookies") ) { + header += "; Secure"; + } + if ( ESAPI.securityConfiguration().getBooleanProp("HttpUtilities.ForceHttpOnlyCookies") ) { + header += "; HttpOnly"; + } + return header; + } + + /** + * Add a cookie to the response after ensuring that there are no encoded or + * illegal characters in the name. + * @param name + * @param date + */ + public void addDateHeader(String name, long date) { + try { + SecurityConfiguration sc = ESAPI.securityConfiguration(); + String safeName = ESAPI.validator().getValidInput("safeSetDateHeader", name, "HTTPHeaderName", sc.getIntProp("HttpUtilities.MaxHeaderNameSize"), false); + getHttpServletResponse().addDateHeader(safeName, date); + } catch (ValidationException e) { + logger.warning(Logger.SECURITY_FAILURE, "Attempt to set invalid date header name denied", e); + } + } + + /** + * 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 + */ + public void addHeader(String name, String value) { + SecurityConfiguration sc = ESAPI.securityConfiguration(); + String strippedName = StringUtilities.stripControls(name); + String strippedValue = StringUtilities.stripControls(value); + String safeName = null; + String safeValue = null; + try { + safeName = ESAPI.validator().getValidInput("addHeader", strippedName, "HTTPHeaderName", sc.getIntProp("HttpUtilities.MaxHeaderNameSize"), false); + } catch (ValidationException e) { + logger.warning(Logger.SECURITY_FAILURE, "Attempt to add invalid header NAME denied: HTTPHeaderName:"+ name, e); + } + + try { + safeValue = ESAPI.validator().getValidInput("addHeader", strippedValue, "HTTPHeaderValue", sc.getIntProp("HttpUtilities.MaxHeaderValueSize"), false); + } catch (ValidationException e) { + logger.warning(Logger.SECURITY_FAILURE, "Attempt to add invalid header VALUE denied: HTTPHeaderName:"+ name, e); + } + + boolean validName = StringUtilities.notNullOrEmpty(safeName, true); + boolean validValue = StringUtilities.notNullOrEmpty(safeValue, true); + + if (validName && validValue) { + getHttpServletResponse().addHeader(safeName, safeValue); + } + } + + /** + * Add a referer header to the response, after validating there are no illegal characters according to the + * Validator.isValidURI() method, as well as ensuring there are no instances of mixed or double encoding + * depending on how you have configured ESAPI defaults. + * @param uri + */ + public void addReferer( String uri) { + + // TODO: make stripping a global config + String strippedValue = StringUtilities.stripControls(uri); + boolean isValidURI = ESAPI.validator().isValidURI("refererHeader", strippedValue, false); + String safeValue = ""; + if(isValidURI) { + safeValue = strippedValue; + } + + getHttpServletResponse().addHeader("referer", safeValue); + } + + /** + * Add an int header to the response after ensuring that there are no + * encoded or illegal characters in the name and value. git + * @param name + * @param value + */ + public void addIntHeader(String name, int value) { + try { + SecurityConfiguration sc = ESAPI.securityConfiguration(); + String safeName = ESAPI.validator().getValidInput("safeSetDateHeader", name, "HTTPHeaderName", sc.getIntProp("HttpUtilities.MaxHeaderNameSize"), false); + getHttpServletResponse().addIntHeader(safeName, value); + } catch (ValidationException e) { + logger.warning(Logger.SECURITY_FAILURE, "Attempt to set invalid int header name denied", e); + } + } + + /** + * Same as HttpServletResponse, no security changes required. + * @param name + * @return True if the current response already contains a header of the supplied name. + */ + public boolean containsHeader(String name) { + return getHttpServletResponse().containsHeader(name); + } + + /** + * Return the URL without any changes, to prevent disclosure of the + * Session ID. The default implementation of this method can add the + * Session ID to the URL if support for cookies is not detected. This + * exposes the Session ID credential in bookmarks, referer headers, server + * logs, and more. + * + * @param url + * @return original url + * @deprecated in servlet spec 2.1. Use + * {@link #encodeRedirectUrl(String)} instead. + */ + @Deprecated + public String encodeRedirectUrl(String url) { + return url; + } + + /** + * Return the URL without any changes, to prevent disclosure of the + * Session ID The default implementation of this method can add the + * Session ID to the URL if support for cookies is not detected. This + * exposes the Session ID credential in bookmarks, referer headers, server + * logs, and more. + * + * @param url + * @return original url + */ + public String encodeRedirectURL(String url) { + return url; + } + + /** + * Return the URL without any changes, to prevent disclosure of the + * Session ID The default implementation of this method can add the + * Session ID to the URL if support for cookies is not detected. This + * exposes the Session ID credential in bookmarks, referer headers, server + * logs, and more. + * + * @param url + * @return original url + * @deprecated in servlet spec 2.1. Use + * {@link #encodeURL(String)} instead. + */ + @Deprecated + public String encodeUrl(String url) { + return url; + } + + /** + * Return the URL without any changes, to prevent disclosure of the + * Session ID The default implementation of this method can add the + * Session ID to the URL if support for cookies is not detected. This + * exposes the Session ID credential in bookmarks, referer headers, server + * logs, and more. + * + * @param url + * @return original url + */ + public String encodeURL(String url) { + return url; + } + + /** + * Same as HttpServletResponse, no security changes required. + * @throws IOException + */ + public void flushBuffer() throws IOException { + getHttpServletResponse().flushBuffer(); + } + + /** + * Same as HttpServletResponse, no security changes required. + * @return The buffer size of the current HTTP response. + */ + public int getBufferSize() { + return getHttpServletResponse().getBufferSize(); + } + + /** + * Same as HttpServletResponse, no security changes required. + * @return The character encoding of the current HTTP response. + */ + public String getCharacterEncoding() { + return getHttpServletResponse().getCharacterEncoding(); + } + + /** + * Same as HttpServletResponse, no security changes required. + * @return The content type of the current HTTP response. + */ + public String getContentType() { + return getHttpServletResponse().getContentType(); + } + + /** + * Same as HttpServletResponse, no security changes required. + * @return The Locale of the current HTTP response. + */ + public Locale getLocale() { + return getHttpServletResponse().getLocale(); + } + + /** + * Same as HttpServletResponse, no security changes required. + * @return The ServletOutputStream of the current HTTP response. + * @throws IOException + */ + public ServletOutputStream getOutputStream() throws IOException { + return getHttpServletResponse().getOutputStream(); + } + + /** + * Same as HttpServletResponse, no security changes required. + * @return The PrintWriter of the current HTTP response. + * @throws IOException + */ + public PrintWriter getWriter() throws IOException { + return getHttpServletResponse().getWriter(); + } + + /** + * Same as HttpServletResponse, no security changes required. + * @return The isCommitted() status of the current HTTP response. + */ + public boolean isCommitted() { + return getHttpServletResponse().isCommitted(); + } + + /** + * Same as HttpServletResponse, no security changes required. + */ + public void reset() { + getHttpServletResponse().reset(); + } + + /** + * Same as HttpServletResponse, no security changes required. + */ + public void resetBuffer() { + getHttpServletResponse().resetBuffer(); + } + + /** + * Override the error code with a 200 in order to confound attackers using + * automated scanners. Overwriting is controlled by {@code HttpUtilities.OverwriteStatusCodes} + * in ESAPI.properties. + * @param sc -- http status code + * @throws IOException + */ + public void sendError(int sc) throws IOException { + SecurityConfiguration config = ESAPI.securityConfiguration(); + if(config.getBooleanProp("HttpUtilities.OverwriteStatusCodes")){ + getHttpServletResponse().sendError(HttpServletResponse.SC_OK, getHTTPMessage(sc)); + }else{ + getHttpServletResponse().sendError(sc, getHTTPMessage(sc)); + } + } + + /** + * Override the error code with a 200 in order to confound attackers using + * automated scanners. The message is canonicalized and filtered for + * dangerous characters. Overwriting is controlled by {@code HttpUtilities.OverwriteStatusCodes} + * in ESAPI.properties. + * @param sc -- http status code + * @param msg -- error message + * @throws IOException + */ + public void sendError(int sc, String msg) throws IOException { + SecurityConfiguration config = ESAPI.securityConfiguration(); + if(config.getBooleanProp("HttpUtilities.OverwriteStatusCodes")){ + getHttpServletResponse().sendError(HttpServletResponse.SC_OK, ESAPI.encoder().encodeForHTML(msg)); + }else{ + getHttpServletResponse().sendError(sc, ESAPI.encoder().encodeForHTML(msg)); + } + } + + /** + * 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. + * @param location + * @throws IOException + */ + public void sendRedirect(String location) throws IOException { + if (!ESAPI.validator().isValidRedirectLocation("Redirect", location, false)) { + logger.fatal(Logger.SECURITY_FAILURE, "Bad redirect location: " + location); + throw new IOException("Redirect failed"); + } + getHttpServletResponse().sendRedirect(location); + } + + /** + * Same as HttpServletResponse, no security changes required. + * @param size + */ + public void setBufferSize(int size) { + getHttpServletResponse().setBufferSize(size); + } + + /** + * Sets the character encoding to the ESAPI configured encoding. + * @param charset + */ + public void setCharacterEncoding(String charset) { + SecurityConfiguration sc = ESAPI.securityConfiguration(); + getHttpServletResponse().setCharacterEncoding(sc.getStringProp("HttpUtilities.CharacterEncoding")); + } + + /** + * Same as HttpServletResponse, no security changes required. + * @param len + */ + public void setContentLength(int len) { + getHttpServletResponse().setContentLength(len); + } + + /** + * Same as HttpServletResponse, no security changes required. + * @param type + */ + public void setContentType(String type) { + getHttpServletResponse().setContentType(type); + } + + /** + * Add a date header to the response after ensuring that there are no + * encoded or illegal characters in the name. + * @param name + * @param date + */ + public void setDateHeader(String name, long date) { + try { + SecurityConfiguration sc = ESAPI.securityConfiguration(); + String safeName = ESAPI.validator().getValidInput("safeSetDateHeader", name, "HTTPHeaderName", sc.getIntProp("HttpUtilities.MaxHeaderNameSize"), false); + getHttpServletResponse().setDateHeader(safeName, date); + } catch (ValidationException e) { + logger.warning(Logger.SECURITY_FAILURE, "Attempt to set invalid date header name denied", e); + } + } + + /** + * 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 + */ + public void setHeader(String name, String value) { + SecurityConfiguration sc = ESAPI.securityConfiguration(); + String strippedName = StringUtilities.stripControls(name); + String strippedValue = StringUtilities.stripControls(value); + String safeName = null; + String safeValue = null; + try { + safeName = ESAPI.validator().getValidInput("setHeader", strippedName, "HTTPHeaderName", sc.getIntProp("HttpUtilities.MaxHeaderNameSize"), false); + } catch (ValidationException e) { + logger.warning(Logger.SECURITY_FAILURE, "Attempt to set invalid header NAME denied: HTTPHeaderName:"+ name, e); + } + + try { + safeValue = ESAPI.validator().getValidInput("setHeader", strippedValue, "HTTPHeaderValue", sc.getIntProp("HttpUtilities.MaxHeaderValueSize"), false); + } catch (ValidationException e) { + logger.warning(Logger.SECURITY_FAILURE, "Attempt to set invalid header VALUE denied: HTTPHeaderName:"+ name, e); + } + + boolean validName = StringUtilities.notNullOrEmpty(safeName, true); + boolean validValue = StringUtilities.notNullOrEmpty(safeValue, true); + + if (validName && validValue) { + getHttpServletResponse().setHeader(safeName, safeValue); + } + } + + /** + * Add an int header to the response after ensuring that there are no + * encoded or illegal characters in the name. + * @param name + * @param value + */ + public void setIntHeader(String name, int value) { + try { + SecurityConfiguration sc = ESAPI.securityConfiguration(); + String safeName = ESAPI.validator().getValidInput("safeSetDateHeader", name, "HTTPHeaderName", sc.getIntProp("HttpUtilities.MaxHeaderNameSize"), false); + getHttpServletResponse().setIntHeader(safeName, value); + } catch (ValidationException e) { + logger.warning(Logger.SECURITY_FAILURE, "Attempt to set invalid int header name denied", e); + } + } + + /** + * Same as HttpServletResponse, no security changes required. + * @param loc + */ + public void setLocale(Locale loc) { + // TODO investigate the character set issues here + getHttpServletResponse().setLocale(loc); + } + + /** + * Override the status code with a 200 in order to confound attackers using + * automated scanners. + * @param sc + */ + public void setStatus(int sc) { + SecurityConfiguration config = ESAPI.securityConfiguration(); + if(config.getBooleanProp("HttpUtilities.OverwriteStatusCodes")){ + getHttpServletResponse().setStatus(HttpServletResponse.SC_OK); + }else{ + getHttpServletResponse().setStatus(sc); + } + + } + + /** + * Override the status code with a 200 in order to confound attackers using + * automated scanners. The message is canonicalized and filtered for + * dangerous characters. + * @param sc + * @param sm + * @deprecated In Servlet spec 2.1. + */ + @Deprecated + public void setStatus(int sc, String sm) { + try { + SecurityConfiguration config = ESAPI.securityConfiguration(); + if(config.getBooleanProp("HttpUtilities.OverwriteStatusCodes")){ + sendError(HttpServletResponse.SC_OK, sm); + }else{ + sendError(sc, sm); + } + } catch (IOException e) { + logger.warning(Logger.SECURITY_FAILURE, "Attempt to set response status failed", e); + } + } + + /** + * returns a text message for the HTTP response code + */ + private String getHTTPMessage(int sc) { + return "HTTP error code: " + sc; + } + +} diff --git a/src/main/java/org/owasp/esapi/filters/package.html b/src/main/java/org/owasp/esapi/filters/package.html new file mode 100644 index 000000000..0efc5ab3d --- /dev/null +++ b/src/main/java/org/owasp/esapi/filters/package.html @@ -0,0 +1,13 @@ + + + + + + + +This package contains several filters that demonstrate ways of using the ESAPI security +controls in front of your application. These filters are intended to be used as examples +that you can customize for your particular application. + + + diff --git a/src/main/java/org/owasp/esapi/logging/appender/ClientInfoSupplier.java b/src/main/java/org/owasp/esapi/logging/appender/ClientInfoSupplier.java new file mode 100644 index 000000000..21d0955c8 --- /dev/null +++ b/src/main/java/org/owasp/esapi/logging/appender/ClientInfoSupplier.java @@ -0,0 +1,92 @@ +/** + * 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. + * + * @created 2019 + */ + +package org.owasp.esapi.logging.appender; + +import java.util.function.Supplier; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.User; + +/** + * Supplier which can provide a String representing the client-side connection + * information. + */ +public class ClientInfoSupplier implements Supplier +{ + /** Default Last Host string if the Authenticated user is null.*/ + private static final String DEFAULT_LAST_HOST = "#UNKNOWN_HOST#"; + /** Session Attribute containing the ESAPI Session id. */ + private static final String ESAPI_SESSION_ATTR = "ESAPI_SESSION"; + /** + * Minimum value for generating a random session value if one is not defined. + */ + private static final int ESAPI_SESSION_RAND_MIN = 0; + /** + * Maximum value for generating a random session value if one is not defined. + */ + private static final int ESAPI_SESSION_RAND_MAX = 1000000; + + /** Format for supplier output. */ + private static final String USER_INFO_FORMAT = "%s@%s"; // SID, USER_HOST_ADDRESS + + /** Whether to log the user info from this instance. */ + private boolean logClientInfo = true; + + // @Override -- Uncomment when we switch to Java 8 as minimal baseline. + public String get() { + String clientInfo = ""; + + if (logClientInfo) { + HttpServletRequest request = ESAPI.currentRequest(); + // create a random session number for the user to represent the user's + // 'session', if it doesn't exist already + String sid = ""; + if (request != null) { + HttpSession session = request.getSession(false); + if (session != null) { + sid = (String) session.getAttribute(ESAPI_SESSION_ATTR); + // 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(ESAPI_SESSION_RAND_MIN, ESAPI_SESSION_RAND_MAX); + session.setAttribute(ESAPI_SESSION_ATTR, sid); + } + } + } + // log user information - username:session@ipaddr + User user = ESAPI.authenticator().getCurrentUser(); + if (user == null) { + clientInfo = String.format(USER_INFO_FORMAT, sid, DEFAULT_LAST_HOST); + } else { + clientInfo = String.format(USER_INFO_FORMAT, sid, user.getLastHostAddress()); + } + } + return clientInfo; + } + + /** + * Specify whether the instance should record the client info. + * + * @param log {@code true} to record + */ + public void setLogClientInfo(boolean log) { + this.logClientInfo = log; + } + +} diff --git a/src/main/java/org/owasp/esapi/logging/appender/EventTypeLogSupplier.java b/src/main/java/org/owasp/esapi/logging/appender/EventTypeLogSupplier.java new file mode 100644 index 000000000..0788d558c --- /dev/null +++ b/src/main/java/org/owasp/esapi/logging/appender/EventTypeLogSupplier.java @@ -0,0 +1,52 @@ +/** + * 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. + * + * @created 2019 + */ + +package org.owasp.esapi.logging.appender; + +import java.util.function.Supplier; + +import org.owasp.esapi.Logger; +import org.owasp.esapi.Logger.EventType; + +/** + * Supplier implementation which returns a consistent String representation of + * an EventType for logging + * + */ +public class EventTypeLogSupplier implements Supplier +{ + /** EventType reference to supply log representation of. */ + private final EventType eventType; + /** Whether to log or not the event type */ + private boolean logEventType = true; + + /** + * Ctr + * + * @param eventType EventType reference to supply log representation for + */ + public EventTypeLogSupplier(EventType eventType) { + this.eventType = eventType == null ? Logger.EVENT_UNSPECIFIED : eventType; + } + + // @Override -- Uncomment when we switch to Java 8 as minimal baseline. + public String get() { + return logEventType ? eventType.toString() : ""; + } + + public void setLogEventType(boolean logEventType) { + this.logEventType = logEventType; + } +} diff --git a/src/main/java/org/owasp/esapi/logging/appender/LogAppender.java b/src/main/java/org/owasp/esapi/logging/appender/LogAppender.java new file mode 100644 index 000000000..b764a7ad4 --- /dev/null +++ b/src/main/java/org/owasp/esapi/logging/appender/LogAppender.java @@ -0,0 +1,35 @@ +/** + * 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. + * + * @created 2019 + */ + +package org.owasp.esapi.logging.appender; + +import org.owasp.esapi.Logger.EventType; + +/** + * Contract interface for appending content to a log message. + * + */ +public interface LogAppender { + + /** + * Creates a replacement Log Message and returns it to the caller. + * @param logName name of the logger. + * @param eventType EventType of the log event being processed. + * @param message The original message. + * @return Updated replacement message. + */ + public String appendTo(String logName, EventType eventType, String message); + +} diff --git a/src/main/java/org/owasp/esapi/logging/appender/LogPrefixAppender.java b/src/main/java/org/owasp/esapi/logging/appender/LogPrefixAppender.java new file mode 100644 index 000000000..237d43ac6 --- /dev/null +++ b/src/main/java/org/owasp/esapi/logging/appender/LogPrefixAppender.java @@ -0,0 +1,119 @@ +/** + * 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. + * + * @created 2019 + */ + +package org.owasp.esapi.logging.appender; + +import org.owasp.esapi.Logger.EventType; + +/** + * LogAppender Implementation which can prefix the common logger information for + * EventType, Client data, and server data. + */ +public class LogPrefixAppender implements LogAppender { + /** Output format used to assemble return values. */ + private static final String RESULT_FORMAT = "[%s] %s"; //Assembled Prefix, MSG + + /** Whether or not to record user information. */ + private final boolean logUserInfo; + /** Whether or not to record client information. */ + private final boolean logClientInfo; + /** Whether or not to record server ip information. */ + private final boolean logServerIp; + /** Whether or not to record application name. */ + private final boolean logApplicationName; + /** Application Name to record. */ + private final String appName; + /** Whether or not to print the prefix. */ + private final boolean logPrefix; + + /** + * Constructor + * + * @param logUserInfo Whether or not to record user information + * @param logClientInfo Whether or not to record client information + * @param logServerIp Whether or not to record server ip information + * @param logApplicationName Whether or not to record application name + * @param appName Application Name to record. + */ + @SuppressWarnings("JavadocReference") + public LogPrefixAppender(boolean logUserInfo, boolean logClientInfo, boolean logServerIp, boolean logApplicationName, String appName) { + this(logUserInfo, logClientInfo, logServerIp, logApplicationName, appName, true); + } + + /** + * Constructor + * + * @param logUserInfo Whether or not to record user information + * @param logClientInfo Whether or not to record client information + * @param logServerIp Whether or not to record server ip information + * @param logApplicationName Whether or not to record application name + * @param appName Application Name to record. + * @param logPrefix Whether or not to print the prefix + */ + public LogPrefixAppender(boolean logUserInfo, boolean logClientInfo, boolean logServerIp, boolean logApplicationName, String appName, boolean logPrefix) { + this.logUserInfo = logUserInfo; + this.logClientInfo = logClientInfo; + this.logServerIp = logServerIp; + this.logApplicationName = logApplicationName; + this.appName = appName; + this.logPrefix = logPrefix; + } + + @Override + public String appendTo(String logName, EventType eventType, String message) { + EventTypeLogSupplier eventTypeSupplier = new EventTypeLogSupplier(eventType); + eventTypeSupplier.setLogEventType(this.logPrefix); + + UserInfoSupplier userInfoSupplier = new UserInfoSupplier(); + userInfoSupplier.setLogUserInfo(logUserInfo); + + ClientInfoSupplier clientInfoSupplier = new ClientInfoSupplier(); + clientInfoSupplier.setLogClientInfo(logClientInfo); + + ServerInfoSupplier serverInfoSupplier = new ServerInfoSupplier(logName); + serverInfoSupplier.setLogServerIp(logServerIp); + serverInfoSupplier.setLogApplicationName(logApplicationName, appName); + serverInfoSupplier.setLogLogName(logPrefix); + + String eventTypeMsg = eventTypeSupplier.get().trim(); + String userInfoMsg = userInfoSupplier.get().trim(); + String clientInfoMsg = clientInfoSupplier.get().trim(); + String serverInfoMsg = serverInfoSupplier.get().trim(); + + //If both user and client have content, then postfix the semicolon to the userInfoMsg at this point to simplify the StringBuilder operations later. + userInfoMsg = (!userInfoMsg.isEmpty() && !clientInfoMsg.isEmpty()) ? userInfoMsg + ":" : userInfoMsg; + + //If both server has content, then prefix the arrow to the serverInfoMsg at this point to simplify the StringBuilder operations later. + serverInfoMsg = (!serverInfoMsg.isEmpty()) ? "-> " + serverInfoMsg: serverInfoMsg; + + String[] optionalPrefixContent = new String[] {userInfoMsg + clientInfoMsg, serverInfoMsg}; + + StringBuilder logPrefixBuilder = new StringBuilder(); + //EventType is always appended (unless we specifically asked not to Log Prefix) + if (this.logPrefix) { + logPrefixBuilder.append(eventTypeMsg); + } + + for (String element : optionalPrefixContent) { + if (!element.isEmpty()) { + logPrefixBuilder.append(" "); + logPrefixBuilder.append(element); + } + } + + String logPrefixContent = logPrefixBuilder.toString(); + return logPrefixContent.trim().isEmpty() ? message : String.format(RESULT_FORMAT, logPrefixContent, message); + } +} diff --git a/src/main/java/org/owasp/esapi/logging/appender/ServerInfoSupplier.java b/src/main/java/org/owasp/esapi/logging/appender/ServerInfoSupplier.java new file mode 100644 index 000000000..88cc786b8 --- /dev/null +++ b/src/main/java/org/owasp/esapi/logging/appender/ServerInfoSupplier.java @@ -0,0 +1,100 @@ +/** + * 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. + * + * @created 2019 + */ + +package org.owasp.esapi.logging.appender; + +import java.util.function.Supplier; + +import javax.servlet.http.HttpServletRequest; + +import org.owasp.esapi.ESAPI; + +/** + * Supplier which can provide a String representing the server-side connection + * information. + */ +public class ServerInfoSupplier implements Supplier +{ + /** Whether to log the server connection info. */ + private boolean logServerIP = true; + /** Whether to log the application name. */ + private boolean logAppName = true; + /** The application name to log. */ + private String applicationName = ""; + /** Whether to log the Name */ + private boolean logLogName = true; + /** Reference to the associated logname/module name. */ + private final String logName; + + /** + * Ctr. + * + * @param logName Reference to the logName to record as the module information + */ + public ServerInfoSupplier(String logName) { + this.logName = logName; + } + + // @Override -- Uncomment when we switch to Java 8 as minimal baseline. + public String get() { + // log server, port, app name, module name -- server:80/app/module + StringBuilder appInfo = new StringBuilder(); + if (logServerIP) { + HttpServletRequest request = ESAPI.currentRequest(); + if (request != null) { + appInfo.append(request.getLocalAddr()).append(":").append(request.getLocalPort()); + } + } + + if (this.logAppName) { + appInfo.append("/").append(this.applicationName); + } + + if (this.logLogName) { + appInfo.append("/").append(logName); + } + + return appInfo.toString(); + } + + /** + * Specify whether the instance should record the server connection info. + * + * @param log {@code true} to record + */ + public void setLogServerIp(boolean log) { + this.logServerIP = log; + } + + /** + * Specify whether the instance should record the prefix. + * + * @param logLogName {@code true} to record + */ + public void setLogLogName(boolean logLogName) { + this.logLogName = logLogName; + } + + /** + * Specify whether the instance should record the application name + * + * @param log {@code true} to record + * @param appName String to record as the application name + */ + public void setLogApplicationName(boolean log, String appName) { + this.logAppName = log; + this.applicationName = appName; + } +} diff --git a/src/main/java/org/owasp/esapi/logging/appender/UserInfoSupplier.java b/src/main/java/org/owasp/esapi/logging/appender/UserInfoSupplier.java new file mode 100644 index 000000000..bf5fd731c --- /dev/null +++ b/src/main/java/org/owasp/esapi/logging/appender/UserInfoSupplier.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. + * + * @created 2019 + */ + +package org.owasp.esapi.logging.appender; + +import java.util.function.Supplier; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.User; + +/** + * Supplier which can provide a String representing the client-side connection + * information. + */ +public class UserInfoSupplier implements Supplier +{ + /** Default UserName string if the Authenticated user is null.*/ + private static final String DEFAULT_USERNAME = "#ANONYMOUS#"; + + /** Whether to log the user info from this instance. */ + private boolean logUserInfo = true; + + // @Override -- Uncomment when we switch to Java 8 as minimal baseline. + public String get() { + // log user information - username:session@ipaddr + User user = ESAPI.authenticator().getCurrentUser(); + + String userInfo = ""; + if (logUserInfo) { + if (user == null) { + userInfo = DEFAULT_USERNAME; + } else { + userInfo = user.getAccountName(); + } + } + + return userInfo; + } + + /** + * Specify whether the instance should record the client info. + * + * @param log {@code true} to record + */ + public void setLogUserInfo(boolean log) { + this.logUserInfo = log; + } +} diff --git a/src/main/java/org/owasp/esapi/logging/cleaning/CodecLogScrubber.java b/src/main/java/org/owasp/esapi/logging/cleaning/CodecLogScrubber.java new file mode 100644 index 000000000..4ce14bac5 --- /dev/null +++ b/src/main/java/org/owasp/esapi/logging/cleaning/CodecLogScrubber.java @@ -0,0 +1,52 @@ +/** + * 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. + * + * @created 2018 + */ +package org.owasp.esapi.logging.cleaning; + +import org.owasp.esapi.codecs.Codec; + +/** + * Implementation of a LogScrubber which passes strings through a delegate codec + * with specific character immunity sets. + * + */ +public class CodecLogScrubber implements LogScrubber { + /** Codec implementation used to scrub messages. */ + private final Codec customizedMessageCodec; + /** + * Set of characters which will not be altered by the codec for this scrubber. + */ + private final char[] immuneMessageChars; + + /** + * Ctr. + * + * @param messageCodec + * Delegate codec. Cannot be {@code null} + * @param immuneChars + * Immune character set. + */ + public CodecLogScrubber(Codec messageCodec, char[] immuneChars) { + if (messageCodec == null) { + throw new IllegalArgumentException("Codec reference cannot be null"); + } + this.customizedMessageCodec = messageCodec; + this.immuneMessageChars = immuneChars == null ? new char[0] : immuneChars; + } + + @Override + public String cleanMessage(String message) { + return customizedMessageCodec.encode(immuneMessageChars, message); + } +} diff --git a/src/main/java/org/owasp/esapi/logging/cleaning/CompositeLogScrubber.java b/src/main/java/org/owasp/esapi/logging/cleaning/CompositeLogScrubber.java new file mode 100644 index 000000000..72da7f2ba --- /dev/null +++ b/src/main/java/org/owasp/esapi/logging/cleaning/CompositeLogScrubber.java @@ -0,0 +1,55 @@ +/** + * 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. + * + * @created 2018 + */ +package org.owasp.esapi.logging.cleaning; + +import java.util.ArrayList; +import java.util.List; + +/** + * LogScrubber implementation which performs iterative delegate to an ordered + * List of LogScrubbers.
+ * The results of the delegate list of LogScrubbers is additive, meaning that + * the original message is passed to the first delegate and its return value + * is passed to the second (etc).
+ * + */ +public class CompositeLogScrubber implements LogScrubber { + /** Delegate scrubbers. */ + private final List messageCleaners; + + /** + * Ctr. + * + * @param orderedCleaner + * Ordered List of delegate implementations. Cannot be {@code null} + */ + public CompositeLogScrubber(List orderedCleaner) { + if (orderedCleaner == null) { + throw new IllegalArgumentException("Delegate LogScrubber List cannot be null"); + } + this.messageCleaners = new ArrayList<>(orderedCleaner); + } + + @Override + public String cleanMessage(String message) { + String cleaned = message; + + for (LogScrubber scrubadub : messageCleaners) { + cleaned = scrubadub.cleanMessage(cleaned); + } + + return cleaned; + } +} diff --git a/src/main/java/org/owasp/esapi/logging/cleaning/LogScrubber.java b/src/main/java/org/owasp/esapi/logging/cleaning/LogScrubber.java new file mode 100644 index 000000000..fd8a54a41 --- /dev/null +++ b/src/main/java/org/owasp/esapi/logging/cleaning/LogScrubber.java @@ -0,0 +1,34 @@ +/** + * 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. + * + * @created 2018 + */ + +package org.owasp.esapi.logging.cleaning; + +/** + * Contract interface for cleaning log message output. + * + */ +public interface LogScrubber { + + /** + * Updates the given message to account for restrictions for this implementation + * and returns the result. + * + * @param message + * Original message to clean. + * @return Cleaned message. + */ + public String cleanMessage(String message); + +} diff --git a/src/main/java/org/owasp/esapi/logging/cleaning/NewlineLogScrubber.java b/src/main/java/org/owasp/esapi/logging/cleaning/NewlineLogScrubber.java new file mode 100644 index 000000000..025896861 --- /dev/null +++ b/src/main/java/org/owasp/esapi/logging/cleaning/NewlineLogScrubber.java @@ -0,0 +1,33 @@ +/** + * 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. + * + * @created 2018 + */ +package org.owasp.esapi.logging.cleaning; + +/** + * LogScrubber implementation which replaces newline and carriage return values. + * + */ +public class NewlineLogScrubber implements LogScrubber { + /** Newline */ + private static final char NEWLINE = '\n'; + /** Carriage Return. */ + private static final char CARRIAGE_RETURN = '\r'; + /** Default Replacement value. */ + private static final char LINE_WRAP_REPLACE = '_'; + + @Override + public String cleanMessage(String message) { + return message.replace(NEWLINE, LINE_WRAP_REPLACE).replace(CARRIAGE_RETURN, LINE_WRAP_REPLACE); + } +} diff --git a/src/main/java/org/owasp/esapi/logging/java/ESAPICustomJavaLevel.java b/src/main/java/org/owasp/esapi/logging/java/ESAPICustomJavaLevel.java new file mode 100644 index 000000000..36a005eb0 --- /dev/null +++ b/src/main/java/org/owasp/esapi/logging/java/ESAPICustomJavaLevel.java @@ -0,0 +1,48 @@ +/** + * 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. + * + * @created 2019 + */ + +package org.owasp.esapi.logging.java; + +import java.util.logging.Level; + +/** + * Definitions of customized Java Logging Level options to map ESAPI behavior to the desired Java Log output behaviors. + */ +public class ESAPICustomJavaLevel extends Level { + + protected static final long serialVersionUID = 1L; + + /** + * Defines a custom error level below SEVERE but above WARNING since this level isn't defined directly + * by java.util.Logger already. + */ + public static final Level ERROR_LEVEL = new ESAPICustomJavaLevel( "ERROR", Level.SEVERE.intValue() - 1); + + /** + * Defines a custom level that should result in content always being recorded, unless the Java Logging configuration is set to OFF. + */ + public static final Level ALWAYS_LEVEL = new ESAPICustomJavaLevel( "ALWAYS", Level.OFF.intValue() - 1); + + /** + * Constructs an instance of a JavaLoggerLevel which essentially provides a mapping between the name of + * the defined level and its numeric value. + * + * @param name The name of the JavaLoggerLevel + * @param value The associated numeric value + */ + private ESAPICustomJavaLevel(String name, int value) { + super(name, value); + } +} diff --git a/src/main/java/org/owasp/esapi/logging/java/ESAPIErrorJavaLevel.java b/src/main/java/org/owasp/esapi/logging/java/ESAPIErrorJavaLevel.java new file mode 100644 index 000000000..f8288c3ad --- /dev/null +++ b/src/main/java/org/owasp/esapi/logging/java/ESAPIErrorJavaLevel.java @@ -0,0 +1,49 @@ +/** + * 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. + * + * @created 2019 + */ + +package org.owasp.esapi.logging.java; + +import java.util.logging.Level; + +/** + * A custom logging level defined between Level.SEVERE and Level.WARNING in logger. + * @deprecated 10/24/2020 : References should use ESAPICustomJavaLevel.ERROR_LEVEL + * @see ESAPICustomJavaLevel#ERROR_LEVEL + */ +@Deprecated +public class ESAPIErrorJavaLevel extends Level { + + protected static final long serialVersionUID = 1L; + + /** + * Defines a custom error level below SEVERE but above WARNING since this level isn't defined directly + * by java.util.Logger already. + * @deprecated + * @see ESAPICustomJavaLevel#ERROR_LEVEL + */ + @Deprecated + public static final Level ERROR_LEVEL = new ESAPIErrorJavaLevel( ESAPICustomJavaLevel.ERROR_LEVEL.getName(),ESAPICustomJavaLevel.ERROR_LEVEL.intValue()); + + /** + * Constructs an instance of a JavaLoggerLevel which essentially provides a mapping between the name of + * the defined level and its numeric value. + * + * @param name The name of the JavaLoggerLevel + * @param value The associated numeric value + */ + private ESAPIErrorJavaLevel(String name, int value) { + super(name, value); + } +} diff --git a/src/main/java/org/owasp/esapi/logging/java/JavaLogBridge.java b/src/main/java/org/owasp/esapi/logging/java/JavaLogBridge.java new file mode 100644 index 000000000..2d1243c05 --- /dev/null +++ b/src/main/java/org/owasp/esapi/logging/java/JavaLogBridge.java @@ -0,0 +1,44 @@ +/** + * 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. + * + * @created 2019 + */ +package org.owasp.esapi.logging.java; + +import java.util.logging.Logger; + +import org.owasp.esapi.Logger.EventType; + +/** + * Contract for translating an ESAPI log event into a Java log event. + * + */ +public interface JavaLogBridge { + /** + * Translation for the provided ESAPI level, type, and message to the specified Java Logger. + * @param logger Logger to receive the translated message. + * @param esapiLevel ESAPI level of event. + * @param type ESAPI event type + * @param message ESAPI event message content. + */ + void log(Logger logger, int esapiLevel, EventType type, String message) ; + /** + * Translation for the provided ESAPI level, type, message, and Throwable to the specified Java Logger. + * @param logger Logger to receive the translated message. + * @param esapiLevel ESAPI level of event. + * @param type ESAPI event type + * @param message ESAPI event message content. + * @param throwable ESAPI event Throwable content + */ + void log(Logger logger, int esapiLevel, EventType type, String message, Throwable throwable) ; + +} diff --git a/src/main/java/org/owasp/esapi/logging/java/JavaLogBridgeImpl.java b/src/main/java/org/owasp/esapi/logging/java/JavaLogBridgeImpl.java new file mode 100644 index 000000000..042a56202 --- /dev/null +++ b/src/main/java/org/owasp/esapi/logging/java/JavaLogBridgeImpl.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) 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. + * + * @created 2019 + */ + +package org.owasp.esapi.logging.java; + +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Logger; + +import org.owasp.esapi.Logger.EventType; +import org.owasp.esapi.logging.appender.LogAppender; +import org.owasp.esapi.logging.cleaning.LogScrubber; + +/** + * Implementation which is intended to bridge the ESAPI Logging API into Java supported Object structures. + * + */ +public class JavaLogBridgeImpl implements JavaLogBridge { + /** Configuration providing associations between esapi log levels and Java levels.*/ + private final Map esapiJavaLevelMap; + /** Cleaner used for log content.*/ + private final LogScrubber scrubber; + /** Appender used for assembling default message content for all logs.*/ + private final LogAppender appender; + + /** + * Constructor. + * @param logScrubber Log message cleaner. + * @param esapiJavaHandlerMap Map identifying ESAPI -> Java log level associations. + */ + public JavaLogBridgeImpl(LogAppender messageAppender, LogScrubber logScrubber, Map esapiJavaHandlerMap) { + //Defensive copy to prevent external mutations. + this.esapiJavaLevelMap = new HashMap<>(esapiJavaHandlerMap); + this.scrubber = logScrubber; + this.appender = messageAppender; + } + @Override + public void log(Logger logger, int esapiLevel, EventType type, String message) { + JavaLogLevelHandler handler = esapiJavaLevelMap.get(esapiLevel); + if (handler == null) { + throw new IllegalArgumentException("Unable to lookup Java level mapping for esapi value of " + esapiLevel); + } + if (handler.isEnabled(logger)) { + String fullMessage = appender.appendTo(logger.getName(), type, message); + String cleanString = scrubber.cleanMessage(fullMessage); + + handler.log(logger, cleanString); + } + } + @Override + public void log(Logger logger, int esapiLevel, EventType type, String message, Throwable throwable) { + JavaLogLevelHandler handler = esapiJavaLevelMap.get(esapiLevel); + if (handler == null) { + throw new IllegalArgumentException("Unable to lookup Java level mapping for esapi value of " + esapiLevel); + } + if (handler.isEnabled(logger)) { + String fullMessage = appender.appendTo(logger.getName(), type, message); + String cleanString = scrubber.cleanMessage(fullMessage); + + handler.log(logger, cleanString, throwable); + } + } +} diff --git a/src/main/java/org/owasp/esapi/logging/java/JavaLogFactory.java b/src/main/java/org/owasp/esapi/logging/java/JavaLogFactory.java new file mode 100644 index 000000000..8cca8fb25 --- /dev/null +++ b/src/main/java/org/owasp/esapi/logging/java/JavaLogFactory.java @@ -0,0 +1,185 @@ +/** + * 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. + * + * @created 2019 + */ +package org.owasp.esapi.logging.java; + +import static org.owasp.esapi.PropNames.APPLICATION_NAME; +import static org.owasp.esapi.PropNames.LOG_APPLICATION_NAME; +import static org.owasp.esapi.PropNames.LOG_CLIENT_INFO; +import static org.owasp.esapi.PropNames.LOG_ENCODING_REQUIRED; +import static org.owasp.esapi.PropNames.LOG_SERVER_IP; +import static org.owasp.esapi.PropNames.LOG_USER_INFO; +import static org.owasp.esapi.PropNames.LOG_PREFIX; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.LogFactory; +import org.owasp.esapi.Logger; +import org.owasp.esapi.codecs.HTMLEntityCodec; +import org.owasp.esapi.errors.ConfigurationException; +import org.owasp.esapi.logging.appender.LogAppender; +import org.owasp.esapi.logging.appender.LogPrefixAppender; +import org.owasp.esapi.logging.cleaning.CodecLogScrubber; +import org.owasp.esapi.logging.cleaning.CompositeLogScrubber; +import org.owasp.esapi.logging.cleaning.LogScrubber; +import org.owasp.esapi.logging.cleaning.NewlineLogScrubber; + +/** + * LogFactory implementation which creates JAVA supporting Loggers. + *

+ * Options for customizing this configuration (in recommended order) + *
    + *
  1. Consider using the SLF4JLogFactory with a java-logging implementation.
  2. + *
  3. Configure the runtime startup command to set the desired system properties for the java.util.logging.LogManager instance. EG: -Djava.util.logging.config.file=/custom/file/path.properties
  4. + *
  5. Overwrite the esapi-java-logging.properties file with the desired logging configurations.
    A default file implementation is available in the configuration jar on GitHub under the 'Releases'
  6. + *
  7. Apply custom-code solution to set the system properties for the java.util.logging.LogManager at runtime. EG: System.setProperty("java.util.logging.config.file", "/custom/file/path.properties");
  8. + *
  9. Create a custom JavaLogFactory class in client project baseline and update the ESAPI.properties configuration to use that reference.
  10. + *
+ * + * @see ESAPI Wiki - Configuration Reference: JavaLogFactory + * + */ +public class JavaLogFactory implements LogFactory { + /**Consistent message offered as a part of the ConfigurationException which is thrown if esapi-java-logging.properties is found on the path. */ + private static final String PROPERTY_CONFIG_MSG = "esapi-java-logging.properties is no longer supported. See https://github.com/ESAPI/esapi-java-legacy/wiki/Configuring-the-JavaLogFactory for information on corrective actions."; + /** Immune characters for the codec log scrubber for JAVA context.*/ + private static final char[] IMMUNE_JAVA_HTML = {',', '.', '-', '_', ' ' }; + /** Codec being used to clean messages for logging.*/ + private static final HTMLEntityCodec HTML_CODEC = new HTMLEntityCodec(); + /** Log appender instance.*/ + private static LogAppender JAVA_LOG_APPENDER; + /** Log cleaner instance.*/ + private static LogScrubber JAVA_LOG_SCRUBBER; + /** Bridge class for mapping esapi -> java log levels.*/ + private static JavaLogBridge LOG_BRIDGE; + + static { + boolean encodeLog = ESAPI.securityConfiguration().getBooleanProp(LOG_ENCODING_REQUIRED); + JAVA_LOG_SCRUBBER = createLogScrubber(encodeLog); + + + boolean logUserInfo = ESAPI.securityConfiguration().getBooleanProp(LOG_USER_INFO); + boolean logClientInfo = ESAPI.securityConfiguration().getBooleanProp(LOG_CLIENT_INFO); + boolean logApplicationName = ESAPI.securityConfiguration().getBooleanProp(LOG_APPLICATION_NAME); + String appName = ESAPI.securityConfiguration().getStringProp(APPLICATION_NAME); + boolean logServerIp = ESAPI.securityConfiguration().getBooleanProp(LOG_SERVER_IP); + + boolean logPrefix = true; + try { + logPrefix = ESAPI.securityConfiguration().getBooleanProp(LOG_PREFIX); + } catch (ConfigurationException ex) { + System.out.println("ESAPI: Failed to read Log Prefix configuration " + LOG_PREFIX + ". Defaulting to enabled" + + ". Caught " + ex.getClass().getName() + + "; exception message was: " + ex); + } + + JAVA_LOG_APPENDER = createLogAppender(logUserInfo, logClientInfo, logServerIp, logApplicationName, appName, logPrefix); + + Map levelLookup = new HashMap<>(); + levelLookup.put(Logger.ALL, JavaLogLevelHandlers.ALWAYS); + levelLookup.put(Logger.TRACE, JavaLogLevelHandlers.FINEST); + levelLookup.put(Logger.DEBUG, JavaLogLevelHandlers.FINE); + levelLookup.put(Logger.INFO, JavaLogLevelHandlers.INFO); + levelLookup.put(Logger.ERROR, JavaLogLevelHandlers.ERROR); + levelLookup.put(Logger.WARNING, JavaLogLevelHandlers.WARNING); + levelLookup.put(Logger.FATAL, JavaLogLevelHandlers.SEVERE); + //LEVEL.OFF not used. If it's off why would we try to log it? + + LOG_BRIDGE = new JavaLogBridgeImpl(JAVA_LOG_APPENDER, JAVA_LOG_SCRUBBER, levelLookup); + + /* + * esapi-java-logging.properties file may lead to confusing logging behavior + * by overriding desired configurations provided through Java's LogManager class. + * + * Verify the file is not present and fail if found to enforce understanding of + * the configuration method. + */ + try (InputStream stream = JavaLogFactory.class.getClassLoader(). + getResourceAsStream("esapi-java-logging.properties")) { + if (stream != null) { + throw new ConfigurationException(PROPERTY_CONFIG_MSG); + } + + } catch (IOException ioe) { + // This is a little strange, I know. + // If the IOException is thrown, then the file actually exists but is malformatted or has some other issue. + // The file should not exist at all, so use the same message as above but include the original exception in the log as well. + throw new ConfigurationException(PROPERTY_CONFIG_MSG, ioe); + } + } + + /** + * Populates the default log scrubber for use in factory-created loggers. + * @param requiresEncoding {@code true} if encoding is required for log content. + * @return LogScrubber instance. + */ + /*package*/ static LogScrubber createLogScrubber(boolean requiresEncoding) { + List messageScrubber = new ArrayList<>(); + messageScrubber.add(new NewlineLogScrubber()); + + if (requiresEncoding) { + messageScrubber.add(new CodecLogScrubber(HTML_CODEC, IMMUNE_JAVA_HTML)); + } + + return new CompositeLogScrubber(messageScrubber); + + } + + /** + * Populates the default log appender for use in factory-created loggers. + * @param appName + * @param logApplicationName + * @param logServerIp + * @param logClientInfo + * + * @return LogAppender instance. + */ + /*package*/ static LogAppender createLogAppender(boolean logUserInfo, boolean logClientInfo, boolean logServerIp, boolean logApplicationName, String appName) { + return new LogPrefixAppender(logUserInfo, logClientInfo, logServerIp, logApplicationName, appName); + } + + /** + * Populates the default log appender for use in factory-created loggers. + * @param appName + * @param logApplicationName + * @param logServerIp + * @param logClientInfo + * @param logPrefix + * + * @return LogAppender instance. + */ + /*package*/ static LogAppender createLogAppender(boolean logUserInfo, boolean logClientInfo, boolean logServerIp, boolean logApplicationName, String appName, boolean logPrefix) { + return new LogPrefixAppender(logUserInfo, logClientInfo, logServerIp, logApplicationName, appName, logPrefix); + } + + + @Override + public Logger getLogger(String moduleName) { + java.util.logging.Logger javaLogger = java.util.logging.Logger.getLogger(moduleName); + return new JavaLogger(javaLogger, LOG_BRIDGE, Logger.ALL); + } + + @Override + public Logger getLogger(@SuppressWarnings("rawtypes") Class clazz) { + java.util.logging.Logger javaLogger = java.util.logging.Logger.getLogger(clazz.getName()); + return new JavaLogger(javaLogger, LOG_BRIDGE, Logger.ALL); + } + +} diff --git a/src/main/java/org/owasp/esapi/logging/java/JavaLogLevelHandler.java b/src/main/java/org/owasp/esapi/logging/java/JavaLogLevelHandler.java new file mode 100644 index 000000000..ea237459d --- /dev/null +++ b/src/main/java/org/owasp/esapi/logging/java/JavaLogLevelHandler.java @@ -0,0 +1,42 @@ +/** + * 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. + * + * @created 2019 + */ +package org.owasp.esapi.logging.java; + +import java.util.logging.Logger; + +/** + * Contract used to isolate translations for each Java Logging Level. + * + * @see JavaLogLevelHandlers + * @see JavaLogBridgeImpl + * + */ +interface JavaLogLevelHandler { + /** Check if the logging level is enabled for the specified logger.*/ + boolean isEnabled(Logger logger); + /** + * Calls the appropriate log level event on the specified logger. + * @param logger Logger to invoke. + * @param msg Message to log. + */ + void log(Logger logger, String msg); + /** + * Calls the appropriate log level event on the specified logger. + * @param logger Logger to invoke + * @param msg Message to log + * @param th Throwable to log. + */ + void log(Logger logger, String msg, Throwable th); +} diff --git a/src/main/java/org/owasp/esapi/logging/java/JavaLogLevelHandlers.java b/src/main/java/org/owasp/esapi/logging/java/JavaLogLevelHandlers.java new file mode 100644 index 000000000..57a90dae7 --- /dev/null +++ b/src/main/java/org/owasp/esapi/logging/java/JavaLogLevelHandlers.java @@ -0,0 +1,52 @@ +/** + * 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. + * + * @created 2019 + */ +package org.owasp.esapi.logging.java; + +import java.util.logging.Level; +import java.util.logging.Logger; + +public enum JavaLogLevelHandlers implements JavaLogLevelHandler { + + SEVERE(Level.SEVERE), + WARNING(Level.WARNING), + INFO(Level.INFO), + CONFIG(Level.CONFIG), + FINE(Level.FINE), + FINER(Level.FINER), + FINEST(Level.FINEST), + ALWAYS(ESAPICustomJavaLevel.ALWAYS_LEVEL), + ERROR(ESAPICustomJavaLevel.ERROR_LEVEL); + + private final Level level; + + private JavaLogLevelHandlers(Level lvl) { + this.level = lvl; + } + + @Override + public boolean isEnabled(Logger logger) { + return logger.isLoggable(level); + } + + @Override + public void log(Logger logger, String msg) { + logger.log(level, msg); + } + + @Override + public void log(Logger logger, String msg, Throwable th) { + logger.log(level, msg, th); + } +} diff --git a/src/main/java/org/owasp/esapi/logging/java/JavaLogger.java b/src/main/java/org/owasp/esapi/logging/java/JavaLogger.java new file mode 100644 index 000000000..1ac4a484f --- /dev/null +++ b/src/main/java/org/owasp/esapi/logging/java/JavaLogger.java @@ -0,0 +1,167 @@ +/** + * 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. + * + * @created 2019 + */ +package org.owasp.esapi.logging.java; + +import org.owasp.esapi.Logger; +/** + * ESAPI Logger implementation which relays events to an Java delegate. + */ +public class JavaLogger implements org.owasp.esapi.Logger { + /** Delegate Logger.*/ + private final java.util.logging.Logger delegate; + /** Handler for translating events from ESAPI context for Java processing.*/ + private final JavaLogBridge logBridge; + /** Maximum log level that will be forwarded to Java from the ESAPI context.*/ + private int loggingLevel; + + /** + * Constructs a new instance. + * @param JavaLogger Delegate Java logger. + * @param bridge Translator for ESAPI -> Java logging events. + * @param defaultEsapiLevel Maximum ESAPI log level events to propagate. + */ + public JavaLogger(java.util.logging.Logger JavaLogger, JavaLogBridge bridge, int defaultEsapiLevel) { + delegate = JavaLogger; + this.logBridge = bridge; + loggingLevel = defaultEsapiLevel; + } + + private void log(int esapiLevel, EventType type, String message) { + if (isEnabled(esapiLevel)) { + logBridge.log(delegate, esapiLevel, type, message); + } + } + + private void log(int esapiLevel, EventType type, String message, Throwable throwable) { + if (isEnabled(esapiLevel)) { + logBridge.log(delegate, esapiLevel, type, message, throwable); + } + } + + + private boolean isEnabled(int esapiLevel) { + return esapiLevel >= loggingLevel; + } + + @Override + public void always(EventType type, String message) { + log (Logger.ALL, type, message); + } + + @Override + public void always(EventType type, String message, Throwable throwable) { + log (Logger.ALL, type, message, throwable); + } + + @Override + public void trace(EventType type, String message) { + log (Logger.TRACE, type, message); + } + + @Override + public void trace(EventType type, String message, Throwable throwable) { + log (Logger.TRACE, type, message, throwable); + } + + @Override + public void debug(EventType type, String message) { + log (Logger.DEBUG, type, message); + } + + @Override + public void debug(EventType type, String message, Throwable throwable) { + log (Logger.DEBUG, type, message, throwable); + } + + @Override + public void info(EventType type, String message) { + log (Logger.INFO, type, message); + } + + @Override + public void info(EventType type, String message, Throwable throwable) { + log (Logger.INFO, type, message, throwable); + } + + @Override + public void warning(EventType type, String message) { + log (Logger.WARNING, type, message); + } + + @Override + public void warning(EventType type, String message, Throwable throwable) { + log (Logger.WARNING, type, message, throwable); + } + + @Override + public void error(EventType type, String message) { + log (Logger.ERROR, type, message); + } + + @Override + public void error(EventType type, String message, Throwable throwable) { + log (Logger.ERROR, type, message, throwable); + } + + @Override + public void fatal(EventType type, String message) { + log (Logger.FATAL, type, message); + } + + @Override + public void fatal(EventType type, String message, Throwable throwable) { + log (Logger.FATAL, type, message, throwable); + } + + @Override + public int getESAPILevel() { + return loggingLevel; + } + + @Override + public boolean isTraceEnabled() { + return isEnabled(Logger.TRACE); + } + + @Override + public boolean isDebugEnabled() { + return isEnabled(Logger.DEBUG); + } + @Override + public boolean isInfoEnabled() { + return isEnabled(Logger.INFO); + } + @Override + public boolean isWarningEnabled() { + return isEnabled(Logger.WARNING); + } + + @Override + public boolean isErrorEnabled() { + return isEnabled(Logger.ERROR); + } + + @Override + public boolean isFatalEnabled() { + return isEnabled(Logger.FATAL); + } + + + @Override + public void setLevel(int level) { + loggingLevel = level; + } + +} diff --git a/src/main/java/org/owasp/esapi/logging/slf4j/Slf4JLogBridge.java b/src/main/java/org/owasp/esapi/logging/slf4j/Slf4JLogBridge.java new file mode 100644 index 000000000..4b73f7a83 --- /dev/null +++ b/src/main/java/org/owasp/esapi/logging/slf4j/Slf4JLogBridge.java @@ -0,0 +1,42 @@ +/** + * 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. + * + * @created 2018 + */ +package org.owasp.esapi.logging.slf4j; + +import org.owasp.esapi.Logger.EventType; +import org.slf4j.Logger; +/** + * Contract for translating an ESAPI log event into an SLF4J log event. + * + */ +public interface Slf4JLogBridge { + /** + * Translation for the provided ESAPI level, type, and message to the specified SLF4J Logger. + * @param logger Logger to receive the translated message. + * @param esapiLevel ESAPI level of event. + * @param type ESAPI event type + * @param message ESAPI event message content. + */ + void log(Logger logger, int esapiLevel, EventType type, String message) ; + /** + * Translation for the provided ESAPI level, type, message, and Throwable to the specified SLF4J Logger. + * @param logger Logger to receive the translated message. + * @param esapiLevel ESAPI level of event. + * @param type ESAPI event type + * @param message ESAPI event message content. + * @param throwable ESAPI event Throwable content + */ + void log(Logger logger, int esapiLevel, EventType type, String message, Throwable throwable) ; + +} diff --git a/src/main/java/org/owasp/esapi/logging/slf4j/Slf4JLogBridgeImpl.java b/src/main/java/org/owasp/esapi/logging/slf4j/Slf4JLogBridgeImpl.java new file mode 100644 index 000000000..44c1a7616 --- /dev/null +++ b/src/main/java/org/owasp/esapi/logging/slf4j/Slf4JLogBridgeImpl.java @@ -0,0 +1,85 @@ +/** + * 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. + * + * @created 2018 + */ + +package org.owasp.esapi.logging.slf4j; + +import java.util.HashMap; +import java.util.Map; + +import org.owasp.esapi.Logger.EventType; +import org.owasp.esapi.logging.appender.LogAppender; +import org.owasp.esapi.logging.cleaning.LogScrubber; +import org.slf4j.IMarkerFactory; +import org.slf4j.Logger; +import org.slf4j.Marker; +import org.slf4j.helpers.BasicMarkerFactory; + +/** + * Implementation which is intended to bridge the ESAPI Logging API into SLF4J supported Object structures. + * + */ +public class Slf4JLogBridgeImpl implements Slf4JLogBridge { + //BasicMarkerFactory uses ConcurrentHashMap to track data. This *should be* thread safe. + private static final IMarkerFactory MARKER_FACTORY = new BasicMarkerFactory(); + /** Configuration providing associations between esapi log levels and SLF4J levels.*/ + private final Map esapiSlfLevelMap; + /** Cleaner used for log content.*/ + private final LogScrubber scrubber; + /** Appender used for assembling default message content for all logs.*/ + private final LogAppender appender; + + /** + * Constructor. + * @param logScrubber Log message cleaner. + * @param esapiSlfHandlerMap Map identifying ESAPI -> SLF4J log level associations. + */ + public Slf4JLogBridgeImpl(LogAppender messageAppender, LogScrubber logScrubber, Map esapiSlfHandlerMap) { + //Defensive copy to prevent external mutations. + this.esapiSlfLevelMap = new HashMap<>(esapiSlfHandlerMap); + this.scrubber = logScrubber; + this.appender = messageAppender; + } + @Override + public void log(Logger logger, int esapiLevel, EventType type, String message) { + Slf4JLogLevelHandler handler = esapiSlfLevelMap.get(esapiLevel); + if (handler == null) { + throw new IllegalArgumentException("Unable to lookup SLF4J level mapping for esapi value of " + esapiLevel); + } + if (handler.isEnabled(logger)) { + type = type == null ? org.owasp.esapi.Logger.EVENT_UNSPECIFIED : type; + String fullMessage = appender.appendTo(logger.getName(), type, message); + String cleanString = scrubber.cleanMessage(fullMessage); + + Marker typeMarker = MARKER_FACTORY.getMarker(type.toString()); + handler.log(logger, typeMarker, cleanString); + } + } + + @Override + public void log(Logger logger, int esapiLevel, EventType type, String message, Throwable throwable) { + Slf4JLogLevelHandler handler = esapiSlfLevelMap.get(esapiLevel); + if (handler == null) { + throw new IllegalArgumentException("Unable to lookup SLF4J level mapping for esapi value of " + esapiLevel); + } + if (handler.isEnabled(logger)) { + type = type == null ? org.owasp.esapi.Logger.EVENT_UNSPECIFIED : type; + String fullMessage = appender.appendTo(logger.getName(), type, message); + String cleanString = scrubber.cleanMessage(fullMessage); + + Marker typeMarker = MARKER_FACTORY.getMarker(type.toString()); + handler.log(logger, typeMarker, cleanString, throwable); + } + } +} diff --git a/src/main/java/org/owasp/esapi/logging/slf4j/Slf4JLogFactory.java b/src/main/java/org/owasp/esapi/logging/slf4j/Slf4JLogFactory.java new file mode 100644 index 000000000..5e1810a93 --- /dev/null +++ b/src/main/java/org/owasp/esapi/logging/slf4j/Slf4JLogFactory.java @@ -0,0 +1,155 @@ +/** + * 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. + * + * @created 2018 + */ +package org.owasp.esapi.logging.slf4j; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.LogFactory; +import org.owasp.esapi.Logger; +import org.owasp.esapi.codecs.HTMLEntityCodec; +import org.owasp.esapi.errors.ConfigurationException; +import org.owasp.esapi.logging.appender.LogAppender; +import org.owasp.esapi.logging.appender.LogPrefixAppender; +import org.owasp.esapi.logging.cleaning.CodecLogScrubber; +import org.owasp.esapi.logging.cleaning.CompositeLogScrubber; +import org.owasp.esapi.logging.cleaning.LogScrubber; +import org.owasp.esapi.logging.cleaning.NewlineLogScrubber; + +import static org.owasp.esapi.PropNames.LOG_ENCODING_REQUIRED; +import static org.owasp.esapi.PropNames.LOG_USER_INFO; +import static org.owasp.esapi.PropNames.LOG_CLIENT_INFO; +import static org.owasp.esapi.PropNames.LOG_APPLICATION_NAME; +import static org.owasp.esapi.PropNames.APPLICATION_NAME; +import static org.owasp.esapi.PropNames.LOG_SERVER_IP; +import static org.owasp.esapi.PropNames.LOG_PREFIX; +import org.slf4j.LoggerFactory; +/** + * LogFactory implementation which creates SLF4J supporting Loggers. + * + */ +public class Slf4JLogFactory implements LogFactory { + /** Html encoding backslash.*/ + private static final char BACKSLASH = '\\'; + /** Html encoding for SLF4J open replacement marker.*/ + private static final char OPEN_SLF_FORMAT='{'; + /** Html encoding for SLF4J close replacement marker.*/ + private static final char CLOSE_SLF_FORMAT='}'; + /** Immune characters for the codec log scrubber for SLF4J context.*/ + private static final char[] IMMUNE_SLF4J_HTML = {',', '.', '-', '_', ' ',BACKSLASH, OPEN_SLF_FORMAT, CLOSE_SLF_FORMAT }; + /** Codec being used to clean messages for logging.*/ + private static final HTMLEntityCodec HTML_CODEC = new HTMLEntityCodec(); + /** Log appender instance.*/ + private static LogAppender SLF4J_LOG_APPENDER; + /** Log cleaner instance.*/ + private static LogScrubber SLF4J_LOG_SCRUBBER; + /** Bridge class for mapping esapi -> slf4j log levels.*/ + private static Slf4JLogBridge LOG_BRIDGE; + + static { + boolean encodeLog = ESAPI.securityConfiguration().getBooleanProp(LOG_ENCODING_REQUIRED); + SLF4J_LOG_SCRUBBER = createLogScrubber(encodeLog); + + + boolean logUserInfo = ESAPI.securityConfiguration().getBooleanProp(LOG_USER_INFO); + boolean logClientInfo = ESAPI.securityConfiguration().getBooleanProp(LOG_CLIENT_INFO); + boolean logApplicationName = ESAPI.securityConfiguration().getBooleanProp(LOG_APPLICATION_NAME); + String appName = ESAPI.securityConfiguration().getStringProp(APPLICATION_NAME); + boolean logServerIp = ESAPI.securityConfiguration().getBooleanProp(LOG_SERVER_IP); + + boolean logPrefix = true; + try { + logPrefix = ESAPI.securityConfiguration().getBooleanProp(LOG_PREFIX); + } catch (ConfigurationException ex) { + System.out.println("ESAPI: Failed to read Log Prefix configuration " + LOG_PREFIX + ". Defaulting to enabled" + + ". Caught " + ex.getClass().getName() + + "; exception message was: " + ex); + } + + SLF4J_LOG_APPENDER = createLogAppender(logUserInfo, logClientInfo, logServerIp, logApplicationName, appName, logPrefix); + + Map levelLookup = new HashMap<>(); + levelLookup.put(Logger.ALL, Slf4JLogLevelHandlers.TRACE); + levelLookup.put(Logger.TRACE, Slf4JLogLevelHandlers.TRACE); + levelLookup.put(Logger.DEBUG, Slf4JLogLevelHandlers.DEBUG); + levelLookup.put(Logger.INFO, Slf4JLogLevelHandlers.INFO); + levelLookup.put(Logger.ERROR, Slf4JLogLevelHandlers.ERROR); + levelLookup.put(Logger.WARNING, Slf4JLogLevelHandlers.WARN); + levelLookup.put(Logger.FATAL, Slf4JLogLevelHandlers.ERROR); + //LEVEL.OFF not used. If it's off why would we try to log it? + + LOG_BRIDGE = new Slf4JLogBridgeImpl(SLF4J_LOG_APPENDER, SLF4J_LOG_SCRUBBER, levelLookup); + } + + /** + * Populates the default log scrubber for use in factory-created loggers. + * @param requiresEncoding {@code true} if encoding is required for log content. + * @return LogScrubber instance. + */ + /*package*/ static LogScrubber createLogScrubber(boolean requiresEncoding) { + List messageScrubber = new ArrayList<>(); + messageScrubber.add(new NewlineLogScrubber()); + + if (requiresEncoding) { + messageScrubber.add(new CodecLogScrubber(HTML_CODEC, IMMUNE_SLF4J_HTML)); + } + + return new CompositeLogScrubber(messageScrubber); + + } + + /** + * Populates the default log appender for use in factory-created loggers. + * @param appName + * @param logApplicationName + * @param logServerIp + * @param logClientInfo + * + * @return LogAppender instance. + */ + /*package*/ static LogAppender createLogAppender(boolean logUserInfo, boolean logClientInfo, boolean logServerIp, boolean logApplicationName, String appName) { + return new LogPrefixAppender(logUserInfo, logClientInfo, logServerIp, logApplicationName, appName); + } + + /** + * Populates the default log appender for use in factory-created loggers. + * @param appName + * @param logApplicationName + * @param logServerIp + * @param logClientInfo + * @param logPrefix + * + * @return LogAppender instance. + */ + /*package*/ static LogAppender createLogAppender(boolean logUserInfo, boolean logClientInfo, boolean logServerIp, boolean logApplicationName, String appName, boolean logPrefix) { + return new LogPrefixAppender(logUserInfo, logClientInfo, logServerIp, logApplicationName, appName, logPrefix); + } + + @Override + public Logger getLogger(String moduleName) { + org.slf4j.Logger slf4JLogger = LoggerFactory.getLogger(moduleName); + return new Slf4JLogger(slf4JLogger, LOG_BRIDGE, Logger.ALL); + } + + @Override + public Logger getLogger(@SuppressWarnings("rawtypes") Class clazz) { + org.slf4j.Logger slf4JLogger = LoggerFactory.getLogger(clazz); + return new Slf4JLogger(slf4JLogger, LOG_BRIDGE, Logger.ALL); + } + +} diff --git a/src/main/java/org/owasp/esapi/logging/slf4j/Slf4JLogLevelHandler.java b/src/main/java/org/owasp/esapi/logging/slf4j/Slf4JLogLevelHandler.java new file mode 100644 index 000000000..1232374a9 --- /dev/null +++ b/src/main/java/org/owasp/esapi/logging/slf4j/Slf4JLogLevelHandler.java @@ -0,0 +1,44 @@ +/** + * 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. + * + * @created 2018 + */ +package org.owasp.esapi.logging.slf4j; + +import org.slf4j.Logger; +import org.slf4j.Marker; +/** + * Contract used to isolate translations for each SLF4J Logging Level. + * + * @see Slf4JLogLevelHandlers + * @see Slf4JLogBridgeImpl + * + */ + interface Slf4JLogLevelHandler { + /** Check if the logging level is enabled for the specified logger.*/ + boolean isEnabled(Logger logger); + /** + * Calls the appropriate log level event on the specified logger. + * @param logger Logger to invoke. + * @param marker Marker to apply to event + * @param msg Message to log. + */ + void log(Logger logger, Marker marker, String msg); + /** + * Calls the appropriate log level event on the specified logger. + * @param logger Logger to invoke + * @param marker Marker to apply to the event. + * @param msg Message to log + * @param th Throwable to log. + */ + void log(Logger logger, Marker marker, String msg, Throwable th); +} diff --git a/src/main/java/org/owasp/esapi/logging/slf4j/Slf4JLogLevelHandlers.java b/src/main/java/org/owasp/esapi/logging/slf4j/Slf4JLogLevelHandlers.java new file mode 100644 index 000000000..e26da6509 --- /dev/null +++ b/src/main/java/org/owasp/esapi/logging/slf4j/Slf4JLogLevelHandlers.java @@ -0,0 +1,113 @@ +/** + * 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. + * + * @created 2018 + */ + +package org.owasp.esapi.logging.slf4j; + +import org.slf4j.Logger; +import org.slf4j.Marker; +/** + * Enumeration capturing the propagation of SLF4J level events. + * + */ +public enum Slf4JLogLevelHandlers implements Slf4JLogLevelHandler { + ERROR { + @Override + public boolean isEnabled(Logger logger) { + return logger.isErrorEnabled(); + } + + @Override + public void log(Logger logger, Marker marker, String msg) { + logger.error(marker, msg); + } + + @Override + public void log(Logger logger, Marker marker, String msg, Throwable th) { + logger.error(marker, msg, th); + } + }, + WARN { + @Override + public boolean isEnabled(Logger logger) { + return logger.isWarnEnabled(); + } + + @Override + public void log(Logger logger, Marker marker, String msg) { + logger.warn(marker, msg); + } + + @Override + public void log(Logger logger, Marker marker, String msg, Throwable th) { + logger.warn(marker, msg, th); + } + }, + INFO { + @Override + public boolean isEnabled(Logger logger) { + return logger.isInfoEnabled(); + } + + @Override + public void log(Logger logger, Marker marker, String msg) { + logger.info(marker, msg); + } + + @Override + public void log(Logger logger, Marker marker, String msg, Throwable th) { + logger.info(marker, msg, th); + } + }, + DEBUG { + @Override + public boolean isEnabled(Logger logger) { + return logger.isDebugEnabled(); + } + + @Override + public void log(Logger logger, Marker marker, String msg) { + logger.debug(marker, msg); + } + + @Override + public void log(Logger logger, Marker marker, String msg, Throwable th) { + logger.debug(marker, msg, th); + } + }, + TRACE{ + + @Override + public boolean isEnabled(Logger logger) { + return logger.isTraceEnabled(); + } + + @Override + public void log(Logger logger, Marker marker, String msg) { + logger.trace(marker, msg); + } + + @Override + public void log(Logger logger, Marker marker, String msg, Throwable th) { + logger.trace(marker, msg, th); + } + + }; + @Override + public abstract boolean isEnabled(Logger logger); + @Override + public abstract void log(Logger logger, Marker marker, String msg); + @Override + public abstract void log(Logger logger, Marker marker, String msg, Throwable th); +} diff --git a/src/main/java/org/owasp/esapi/logging/slf4j/Slf4JLogger.java b/src/main/java/org/owasp/esapi/logging/slf4j/Slf4JLogger.java new file mode 100644 index 000000000..adb64ce20 --- /dev/null +++ b/src/main/java/org/owasp/esapi/logging/slf4j/Slf4JLogger.java @@ -0,0 +1,167 @@ +/** + * 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. + * + * @created 2018 + */ +package org.owasp.esapi.logging.slf4j; + +import org.owasp.esapi.Logger; +/** + * ESAPI Logger implementation which relays events to an SLF4J delegate. + */ +public class Slf4JLogger implements org.owasp.esapi.Logger { + /** Delegate Logger.*/ + private final org.slf4j.Logger delegate; + /** Handler for translating events from ESAPI context for SLF4J processing.*/ + private final Slf4JLogBridge logBridge; + /** Maximum log level that will be forwarded to SLF4J from the ESAPI context.*/ + private int loggingLevel; + + /** + * Constructs a new instance. + * @param slf4JLogger Delegate SLF4J logger. + * @param bridge Translator for ESAPI -> SLF4J logging events. + * @param defaultEsapiLevel Maximum ESAPI log level events to propagate. + */ + public Slf4JLogger(org.slf4j.Logger slf4JLogger, Slf4JLogBridge bridge, int defaultEsapiLevel) { + delegate = slf4JLogger; + this.logBridge = bridge; + loggingLevel = defaultEsapiLevel; + } + + private void log(int esapiLevel, EventType type, String message) { + if (isEnabled(esapiLevel)) { + logBridge.log(delegate, esapiLevel, type, message); + } + } + + private void log(int esapiLevel, EventType type, String message, Throwable throwable) { + if (isEnabled(esapiLevel)) { + logBridge.log(delegate, esapiLevel, type, message, throwable); + } + } + + + private boolean isEnabled(int esapiLevel) { + return esapiLevel >= loggingLevel; + } + + @Override + public void always(EventType type, String message) { + log (Logger.ALL, type, message); + } + + @Override + public void always(EventType type, String message, Throwable throwable) { + log (Logger.ALL, type, message, throwable); + } + + @Override + public void trace(EventType type, String message) { + log (Logger.TRACE, type, message); + } + + @Override + public void trace(EventType type, String message, Throwable throwable) { + log (Logger.TRACE, type, message, throwable); + } + + @Override + public void debug(EventType type, String message) { + log (Logger.DEBUG, type, message); + } + + @Override + public void debug(EventType type, String message, Throwable throwable) { + log (Logger.DEBUG, type, message, throwable); + } + + @Override + public void info(EventType type, String message) { + log (Logger.INFO, type, message); + } + + @Override + public void info(EventType type, String message, Throwable throwable) { + log (Logger.INFO, type, message, throwable); + } + + @Override + public void warning(EventType type, String message) { + log (Logger.WARNING, type, message); + } + + @Override + public void warning(EventType type, String message, Throwable throwable) { + log (Logger.WARNING, type, message, throwable); + } + + @Override + public void error(EventType type, String message) { + log (Logger.ERROR, type, message); + } + + @Override + public void error(EventType type, String message, Throwable throwable) { + log (Logger.ERROR, type, message, throwable); + } + + @Override + public void fatal(EventType type, String message) { + log (Logger.FATAL, type, message); + } + + @Override + public void fatal(EventType type, String message, Throwable throwable) { + log (Logger.FATAL, type, message, throwable); + } + + @Override + public int getESAPILevel() { + return loggingLevel; + } + + @Override + public boolean isTraceEnabled() { + return isEnabled(Logger.TRACE); + } + + @Override + public boolean isDebugEnabled() { + return isEnabled(Logger.DEBUG); + } + @Override + public boolean isInfoEnabled() { + return isEnabled(Logger.INFO); + } + @Override + public boolean isWarningEnabled() { + return isEnabled(Logger.WARNING); + } + + @Override + public boolean isErrorEnabled() { + return isEnabled(Logger.ERROR); + } + + @Override + public boolean isFatalEnabled() { + return isEnabled(Logger.FATAL); + } + + + @Override + public void setLevel(int level) { + loggingLevel = level; + } + +} diff --git a/src/main/java/org/owasp/esapi/package.html b/src/main/java/org/owasp/esapi/package.html new file mode 100644 index 000000000..a5e2252c3 --- /dev/null +++ b/src/main/java/org/owasp/esapi/package.html @@ -0,0 +1,85 @@ + + + + + + + +The ESAPI interfaces and {@code 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, but is useful in many ways +by itself as well. +

+OWASP ESAPI interfaces and reference implementation provides +enterprise web application developers with the most important +security functions they need in ordre to build secure web applications +and web services that stand up to most common-day web-based attacks. +

+

Sponsor

+

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 Java 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#tab=Java_EE.

+ +

ESAPI Architecture

+ +

The ESAPI class library builds on the excellent security libraries available, +such as Java Logging, JCE, and Apache Commons FileUpload. It uses the +concepts from many of the security packages out there, such as Spring Security, +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.

+ + + +

Addressing OWASP Top Ten

+ +

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.

+ + +

Copyright and License

+ +

This project and all associated code is Copyright (c) 2007 - The OWASP Foundation

+ +

This project licensed under the BSD license, +which is very permissive and about as close to public domain as is possible. You can use or modify +ESAPI however you want, even include it in commercial products.

+ +

References

+ +This library builds on some of the ideas found in: + + + + diff --git a/src/main/java/org/owasp/esapi/reference/AbstractAccessReferenceMap.java b/src/main/java/org/owasp/esapi/reference/AbstractAccessReferenceMap.java new file mode 100644 index 000000000..c17109913 --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/AbstractAccessReferenceMap.java @@ -0,0 +1,240 @@ +/** + * 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.reference; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +import org.owasp.esapi.AccessReferenceMap; +import org.owasp.esapi.errors.AccessControlException; + +/** + * Abstract Implementation of the AccessReferenceMap. + *
+ * Implementation offers default synchronization on all public API + * to assist with thread safety. + *
+ * For complex interactions spanning multiple calls, it is recommended + * to add a synchronized block around all invocations to maintain intended data integrity. + * + *
+ * public MyClassUsingAARM {
+ *  private AbstractAccessReferenceMap aarm;
+ *
+ *  public void replaceAARMDirect(Object oldDirect, Object newDirect) {
+ *     synchronized (aarm) {
+ *        aarm.removeDirectReference(oldDirect);
+ *        aarm.addDirectReference(newDirect);
+ *     }
+ *  }
+ * }
+ * 
+ * @author  Chris Schmidt (chrisisbeef@gmail.com)
+ * @since   July 21, 2009
+ */
+public abstract class AbstractAccessReferenceMap implements AccessReferenceMap
+{
+   private static final long serialVersionUID = 238742764284682230L;
+
+   /** The Indirect to Direct Map */
+   protected Map itod;
+   /** The Direct to Indirect Map */
+   protected Map dtoi;
+
+   /**
+    * Instantiates a new access reference map. Note that this will create the underlying Maps with an initialSize
+    * of {@link HashMap#DEFAULT_INITIAL_CAPACITY} and that resizing a Map is an expensive process. Consider
+    * using a constructor where the initialSize is passed in to maximize performance of the AccessReferenceMap.
+    *
+    * @see #AbstractAccessReferenceMap(java.util.Set, int)
+    * @see #AbstractAccessReferenceMap(int)
+    */
+   public AbstractAccessReferenceMap() {
+      itod = new HashMap();
+      dtoi = new HashMap();
+   }
+
+   /**
+    * Instantiates a new access reference map with the specified size allotment
+    * to reduce Map resizing overhead.
+    *
+    * @param initialSize
+    *          The initial size of the underlying maps
+    */
+   public AbstractAccessReferenceMap( int initialSize ) {
+      itod = new HashMap(initialSize);
+      dtoi = new HashMap(initialSize);
+   }
+
+   /**
+    * Instantiates a new access reference map with a set of direct references.
+    *
+    * @param directReferences
+    *            the direct references
+    * @deprecated This constructor internally calls the abstract method
+    *    {@link #getUniqueReference()}. Since this is a constructor, any
+    *    subclass that implements getUniqueReference() has not had its
+    *    own constructor run. This leads to strange bugs because subclass
+    *    internal state is initialized after calls to getUniqueReference()
+    *    have already happened. If this constructor is desired in a
+    *    subclass, consider running {@link #update(Set)} in the subclass
+    *    constructor instead.
+    */
+   @Deprecated
+   public AbstractAccessReferenceMap( Set directReferences ) {
+      itod = new HashMap(directReferences.size());
+      dtoi = new HashMap(directReferences.size());
+      update(directReferences);
+   }
+
+   /**
+    * Instantiates a new access reference map with the specified size allotment
+    * and initializes the map with the passed in references. Note that if you pass
+    * in an initialSize that is less than the size of the passed in set, the map will
+    * need to be resized while it is being loaded with the references, so it is
+    * best practice to verify that the size being passed in is always larger than
+    * the size of the set that is being passed in.
+    *
+    * @param directReferences
+    *          The references to initialize the access reference map
+    * @param initialSize
+    *          The initial size to set the map to.
+    *
+    * @deprecated This constructor internally calls the abstract method
+    *    {@link #getUniqueReference()}. Since this is a constructor, any
+    *    subclass that implements getUniqueReference() has not had its
+    *    own constructor run. This leads to strange bugs because subclass
+    *    internal state is initialized after calls to getUniqueReference()
+    *    have already happened. If this constructor is desired in a
+    *    subclass, consider running {@link #update(Set)} in the subclass
+    *    constructor instead.
+    */
+   @Deprecated
+   public AbstractAccessReferenceMap( Set directReferences, int initialSize ) {
+      itod = new HashMap(initialSize);
+      dtoi = new HashMap(initialSize);
+      update(directReferences);
+   }
+
+   /**
+    * Returns a Unique Reference Key to be associated with a new directReference being
+    * inserted into the AccessReferenceMap.
+    *
+    * @return Reference Identifier
+    */
+   protected abstract K getUniqueReference();
+
+   /**
+   * {@inheritDoc}
+   */
+   public synchronized Iterator iterator() {
+      TreeSet sorted = new TreeSet(dtoi.keySet());
+      return sorted.iterator();
+   }
+
+   /**
+   * {@inheritDoc}
+   */
+   public synchronized  K addDirectReference(T direct) {
+      if ( dtoi.keySet().contains( direct ) ) {
+         return dtoi.get( direct );
+      }
+      K indirect = getUniqueReference();
+      itod.put(indirect, direct);
+      dtoi.put(direct, indirect);
+      return indirect;
+   }
+
+   /**
+   * {@inheritDoc}
+   */
+   public synchronized  K removeDirectReference(T direct) throws AccessControlException
+   {
+      K indirect = dtoi.get(direct);
+      if ( indirect != null ) {
+         itod.remove(indirect);
+         dtoi.remove(direct);
+      }
+      return indirect;
+   }
+
+   /**
+   * {@inheritDoc}
+   */
+   public final synchronized void update(Set directReferences) {
+       Map new_dtoi = new HashMap( directReferences.size() );
+       Map new_itod = new HashMap( directReferences.size() );
+
+       Set newDirect = new HashSet<>(directReferences);
+       Set dtoiCurrent = new HashSet<>(dtoi.keySet());
+
+       //Preserve all keys that are in the new set
+       dtoiCurrent.retainAll(newDirect);
+
+       //Transfer existing values into the new map
+       for (Object current: dtoiCurrent) {
+           K idCurrent = dtoi.get(current);
+           new_dtoi.put(current, idCurrent);
+           new_itod.put(idCurrent, current);
+       }
+
+       //Trim the new map to only new values
+       newDirect.removeAll(dtoiCurrent);
+
+       //Add new values with new indirect keys to the new map
+       for (Object newD : newDirect) {
+           K idCurrent;
+           do {
+               idCurrent = getUniqueReference();
+               //Unlikey, but just in case we generate the exact same key multiple times...
+           } while (dtoi.containsValue(idCurrent));
+
+           new_dtoi.put(newD, idCurrent);
+           new_itod.put(idCurrent, newD);
+       }
+
+       dtoi = new_dtoi;
+       itod = new_itod;
+   }
+
+   /**
+   * {@inheritDoc}
+   */
+   public synchronized  K getIndirectReference(T directReference) {
+      return dtoi.get(directReference);
+   }
+
+   /**
+   * {@inheritDoc}
+   */
+   public synchronized  T getDirectReference(K indirectReference) throws AccessControlException {
+      if (itod.containsKey(indirectReference) ) {
+         try
+         {
+            return (T) itod.get(indirectReference);
+         }
+         catch (ClassCastException e)
+         {
+            throw new AccessControlException("Access denied.", "Request for incorrect type reference: " + indirectReference);
+         }
+      }
+      throw new AccessControlException("Access denied", "Request for invalid indirect reference: " + indirectReference);
+   }
+}
diff --git a/src/main/java/org/owasp/esapi/reference/AbstractAuthenticator.java b/src/main/java/org/owasp/esapi/reference/AbstractAuthenticator.java
new file mode 100644
index 000000000..9e3f7843b
--- /dev/null
+++ b/src/main/java/org/owasp/esapi/reference/AbstractAuthenticator.java
@@ -0,0 +1,300 @@
+package org.owasp.esapi.reference;
+
+import java.util.Date;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.owasp.esapi.ESAPI;
+import org.owasp.esapi.HTTPUtilities;
+import org.owasp.esapi.Logger;
+import org.owasp.esapi.User;
+import org.owasp.esapi.errors.AccessControlException;
+import org.owasp.esapi.errors.AuthenticationCredentialsException;
+import org.owasp.esapi.errors.AuthenticationException;
+import org.owasp.esapi.errors.AuthenticationLoginException;
+import org.owasp.esapi.errors.EnterpriseSecurityException;
+/**
+ * A partial implementation of the Authenticator interface.
+ * This class should not implement any methods that would be meant
+ * to modify a User object, since that's probably implementation specific.
+ *
+ */
+public abstract class AbstractAuthenticator implements org.owasp.esapi.Authenticator {
+
+    /**
+     * Key for user in session
+     */
+    protected static final String USER = "ESAPIUserSessionKey";
+
+    private final Logger logger = ESAPI.getLogger("Authenticator");
+
+    /**
+     * The currentUser ThreadLocal variable is used to make the currentUser available to any call in any part of an
+     * application. Otherwise, each thread would have to pass the User object through the calltree to any methods that
+     * need it. Because we want exceptions and log calls to contain user data, that could be almost anywhere. Therefore,
+     * the ThreadLocal approach simplifies things greatly. 

As a possible extension, one could create a delegation + * framework by adding another ThreadLocal to hold the delegating user identity. + */ + private final ThreadLocalUser currentUser = new ThreadLocalUser(); + + private class ThreadLocalUser extends InheritableThreadLocal { + + public User initialValue() { + return User.ANONYMOUS; + } + + public User getUser() { + return super.get(); + } + + public void setUser(User newUser) { + super.set(newUser); + } + } + + /** + * + */ + public AbstractAuthenticator() { + super(); + } + + /** + * {@inheritDoc} + */ + public void clearCurrent() { + // logger.logWarning(Logger.SECURITY, "************Clearing threadlocals. Thread" + Thread.currentThread().getName() ); + currentUser.setUser(null); + } + + /** + * {@inheritDoc} + */ + public boolean exists(String accountName) { + return getUser(accountName) != null; + } + + /** + * {@inheritDoc} + *

+ * Returns the currently logged user as set by the setCurrentUser() methods. Must not log in this method because the + * logger calls getCurrentUser() and this could cause a loop. + */ + public User getCurrentUser() { + User user = currentUser.get(); + if (user == null) { + user = User.ANONYMOUS; + } + return user; + } + + /** + * Gets the user from session. + * + * @return the user from session or null if no user is found in the session + */ + protected User getUserFromSession() { + HTTPUtilities httpUtils = ESAPI.httpUtilities(); + HttpServletRequest req = httpUtils.getCurrentRequest(); + HttpSession session = req.getSession(false); + if (session == null) return null; + return ESAPI.httpUtilities().getSessionAttribute(USER); + } + + /** + * Returns the user if a matching remember token is found, or null if the token + * is missing, token is corrupt, token is expired, account name does not match + * and existing account, or hashed password does not match user's hashed password. + * + * @return the user if a matching remember token is found, or null if the token + * is missing, token is corrupt, token is expired, account name does not match + * and existing account, or hashed password does not match user's hashed password. + */ + protected DefaultUser getUserFromRememberToken() { + try { + HTTPUtilities utils =ESAPI.httpUtilities(); + String token = utils.getCookie(ESAPI.currentRequest(), HTTPUtilities.REMEMBER_TOKEN_COOKIE_NAME); + if (token == null) return null; + + // See Google Issue 144 regarding first URLDecode the token and THEN unsealing. + // Note that this Google Issue was marked as "WontFix". + + String[] data = ESAPI.encryptor().unseal(token).split("\\|"); + if (data.length != 2) { + logger.warning(Logger.SECURITY_FAILURE, "Found corrupt or expired remember token"); + ESAPI.httpUtilities().killCookie(ESAPI.currentRequest(), ESAPI.currentResponse(), HTTPUtilities.REMEMBER_TOKEN_COOKIE_NAME); + return null; + } + + String username = data[0]; + String password = data[1]; + DefaultUser user = (DefaultUser) getUser(username); + if (user == null) { + logger.warning(Logger.SECURITY_FAILURE, "Found valid remember token but no user matching " + username); + return null; + } + + logger.info(Logger.SECURITY_SUCCESS, "Logging in user with remember token: " + user.getAccountName()); + user.loginWithPassword(password); + return user; + } catch (AuthenticationException ae) { + logger.warning(Logger.SECURITY_FAILURE, "Login via remember me cookie failed", ae); + } catch (EnterpriseSecurityException e) { + logger.warning(Logger.SECURITY_FAILURE, "Remember token was missing, corrupt, or expired"); + } + ESAPI.httpUtilities().killCookie(ESAPI.currentRequest(), ESAPI.currentResponse(), HTTPUtilities.REMEMBER_TOKEN_COOKIE_NAME); + return null; + } + + /** + * Utility method to extract credentials and verify them. + * + * @param request The current HTTP request + * @return The user that successfully authenticated + * @throws AuthenticationException if the submitted credentials are invalid. + */ + private User loginWithUsernameAndPassword(HttpServletRequest request) throws AuthenticationException { + + String username = request.getParameter(ESAPI.securityConfiguration().getUsernameParameterName()); + String password = request.getParameter(ESAPI.securityConfiguration().getPasswordParameterName()); + + // if a logged-in user is requesting to login, log them out first + User user = getCurrentUser(); + if (user != null && !user.isAnonymous()) { + logger.warning(Logger.SECURITY_SUCCESS, "User requested relogin. Performing logout then authentication"); + user.logout(); + } + + // now authenticate with username and password + if (username == null || password == null) { + if (username == null) { + username = "unspecified user"; + } + throw new AuthenticationCredentialsException("Authentication failed", "Authentication failed for " + username + " because of null username or password"); + } + user = getUser(username); + if (user == null) { + throw new AuthenticationCredentialsException("Authentication failed", "Authentication failed because user " + username + " doesn't exist"); + } + user.loginWithPassword(password); + + request.setAttribute(user.getCSRFToken(), "authenticated"); + return user; + } + + /** + * {@inheritDoc} + */ + public User login() throws AuthenticationException { + return login(ESAPI.currentRequest(), ESAPI.currentResponse()); + } + + /** + * {@inheritDoc} + */ + public User login(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { + + if (request == null || response == null) { + throw new AuthenticationCredentialsException("Invalid request", "Request or response objects were null"); + } + + // if there's a user in the session then use that + DefaultUser user = (DefaultUser) getUserFromSession(); + + // else if there's a remember token then use that + if (user == null) { + user = getUserFromRememberToken(); + } + + // else try to verify credentials - throws exception if login fails + if (user == null) { + user = (DefaultUser) loginWithUsernameAndPassword(request); + } + + // set last host address + user.setLastHostAddress(request.getRemoteHost()); + + // warn if this authentication request was not POST or non-SSL connection, exposing credentials or session id + try { + ESAPI.httpUtilities().assertSecureRequest(ESAPI.currentRequest()); + } catch (AccessControlException e) { + throw new AuthenticationException("Attempt to login with an insecure request", e.getLogMessage(), e); + } + + // don't let anonymous user log in + if (user.isAnonymous()) { + user.logout(); + throw new AuthenticationLoginException("Login failed", "Anonymous user cannot be set to current user. User: " + user.getAccountName()); + } + + // don't let disabled users log in + if (!user.isEnabled()) { + user.logout(); + user.incrementFailedLoginCount(); + user.setLastFailedLoginTime(new Date()); + throw new AuthenticationLoginException("Login failed", "Disabled user cannot be set to current user. User: " + user.getAccountName()); + } + + // don't let locked users log in + if (user.isLocked()) { + user.logout(); + user.incrementFailedLoginCount(); + user.setLastFailedLoginTime(new Date()); + throw new AuthenticationLoginException("Login failed", "Locked user cannot be set to current user. User: " + user.getAccountName()); + } + + // don't let expired users log in + if (user.isExpired()) { + user.logout(); + user.incrementFailedLoginCount(); + user.setLastFailedLoginTime(new Date()); + throw new AuthenticationLoginException("Login failed", "Expired user cannot be set to current user. User: " + user.getAccountName()); + } + + // check session inactivity timeout + if (user.isSessionTimeout()) { + user.logout(); + user.incrementFailedLoginCount(); + user.setLastFailedLoginTime(new Date()); + throw new AuthenticationLoginException("Login failed", "Session inactivity timeout: " + user.getAccountName()); + } + + // check session absolute timeout + if (user.isSessionAbsoluteTimeout()) { + user.logout(); + user.incrementFailedLoginCount(); + user.setLastFailedLoginTime(new Date()); + throw new AuthenticationLoginException("Login failed", "Session absolute timeout: " + user.getAccountName()); + } + + //set Locale to the user object in the session from request + user.setLocale(request.getLocale()); + + // create new session for this User + HttpSession session = request.getSession(); + user.addSession(session); + session.setAttribute(USER, user); + setCurrentUser(user); + return user; + } + + /** + * {@inheritDoc} + */ + public void logout() { + User user = getCurrentUser(); + if (user != null && !user.isAnonymous()) { + user.logout(); + } + } + + /** + * {@inheritDoc} + */ + public void setCurrentUser(User user) { + currentUser.setUser(user); + } + +} diff --git a/src/main/java/org/owasp/esapi/reference/DefaultAccessController.java b/src/main/java/org/owasp/esapi/reference/DefaultAccessController.java new file mode 100644 index 000000000..7f978ca37 --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/DefaultAccessController.java @@ -0,0 +1,147 @@ +package org.owasp.esapi.reference; + +import java.util.Map; + +import org.owasp.esapi.AccessControlRule; +import org.owasp.esapi.AccessController; +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Logger; +import org.owasp.esapi.errors.AccessControlException; +import org.owasp.esapi.reference.accesscontrol.policyloader.ACRPolicyFileLoader; +import org.owasp.esapi.reference.accesscontrol.policyloader.PolicyDTO; + +public class DefaultAccessController implements AccessController { + private Map ruleMap; + + private static volatile AccessController singletonInstance = null; + + public static AccessController getInstance() throws AccessControlException { + if ( singletonInstance == null ) { + synchronized ( DefaultAccessController.class ) { + if ( singletonInstance == null ) { + singletonInstance = new DefaultAccessController(); + } + } + } + return singletonInstance; + } + + protected final Logger logger = ESAPI.getLogger("DefaultAccessController"); + + private DefaultAccessController() throws AccessControlException { + ACRPolicyFileLoader policyDescriptor = new ACRPolicyFileLoader(); + PolicyDTO policyDTO = policyDescriptor.load(); + ruleMap = policyDTO.getAccessControlRules(); + } + + /** + * {@inheritDoc} + */ + public boolean isAuthorized(Object key, Object runtimeParameter) { + try { + AccessControlRule rule = (AccessControlRule)ruleMap.get(key); + if(rule == null) { + throw new AccessControlException("Access Denied", + "AccessControlRule was not found for key: " + key); + } + if(logger.isDebugEnabled()){ logger.debug(Logger.EVENT_SUCCESS, "Evaluating Authorization Rule \"" + key + "\" Using class: " + rule.getClass().getCanonicalName()); } + return rule.isAuthorized(runtimeParameter); + } catch(Exception e) { + try { + //Log the exception by throwing and then catching it. + //TODO figure out what which string goes where. + throw new AccessControlException("Access Denied", + "An unhandled Exception was " + + "caught, so access is denied.", + e); + } catch(AccessControlException ace) { + //the exception was just logged. There's nothing left to do. + } + return false; //fail closed + } + } + + /** {@inheritDoc} */ + public void assertAuthorized(Object key, Object runtimeParameter) throws AccessControlException { + boolean isAuthorized; + try { + AccessControlRule rule = (AccessControlRule)ruleMap.get(key); + if(rule == null) { + throw new AccessControlException("Access Denied", + "AccessControlRule was not found for key: " + key); + } + if(logger.isDebugEnabled()){ logger.debug(Logger.EVENT_SUCCESS, "Asserting Authorization Rule \"" + key + "\" Using class: " + rule.getClass().getCanonicalName()); } + isAuthorized = rule.isAuthorized(runtimeParameter); + } catch(Exception e) { + //TODO figure out what which string goes where. + throw new AccessControlException("Access Denied", "An unhandled Exception was " + + "caught, so access is denied." + + "AccessControlException.", + e); + } + if(!isAuthorized) { + throw new AccessControlException("Access Denied", + "Access Denied for key: " + key + + " runtimeParameter: " + runtimeParameter); + } + } + + /** {@inheritDoc} */ + public void assertAuthorizedForData(String action, Object data) + throws AccessControlException { + this.assertAuthorized("AC 1.0 Data", new Object[] {action, data}); + } + + /** + * {@inheritDoc} + * @deprecated + */ + @Deprecated + public void assertAuthorizedForFile(String filepath) + throws AccessControlException { + this.assertAuthorized("AC 1.0 File", new Object[] {filepath}); + } + + /** {@inheritDoc} */ + public void assertAuthorizedForFunction(String functionName) + throws AccessControlException { + this.assertAuthorized("AC 1.0 Function", new Object[] {functionName}); + } + + /** {@inheritDoc} */ + public void assertAuthorizedForService(String serviceName) + throws AccessControlException { + this.assertAuthorized("AC 1.0 Service", new Object[] {serviceName}); + } + + /** {@inheritDoc} */ + public void assertAuthorizedForURL(String url) + throws AccessControlException { + this.assertAuthorized("AC 1.0 URL", new Object[] {url}); + } + + /** {@inheritDoc} */ + public boolean isAuthorizedForData(String action, Object data) { + return this.isAuthorized("AC 1.0 Data", new Object[] {action, data}); + } + + /** {@inheritDoc} */ + public boolean isAuthorizedForFile(String filepath) { + return this.isAuthorized("AC 1.0 File", new Object[] {filepath}); + } + + /** {@inheritDoc} */ + public boolean isAuthorizedForFunction(String functionName) { + return this.isAuthorized("AC 1.0 Function", new Object[] {functionName}); + } + + /** {@inheritDoc} */ + public boolean isAuthorizedForService(String serviceName) { + return this.isAuthorized("AC 1.0 Service", new Object[] {serviceName}); + } + + /** {@inheritDoc} */ + public boolean isAuthorizedForURL(String url) { + return this.isAuthorized("AC 1.0 URL", new Object[] {url}); + } +} diff --git a/src/main/java/org/owasp/esapi/reference/DefaultEncoder.java b/src/main/java/org/owasp/esapi/reference/DefaultEncoder.java new file mode 100644 index 000000000..2b87e0d34 --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/DefaultEncoder.java @@ -0,0 +1,764 @@ +/** + * 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.reference; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Encoder; +import org.owasp.esapi.Logger; +import org.owasp.esapi.SecurityConfiguration; +import org.owasp.esapi.codecs.Base64; +import org.owasp.esapi.codecs.CSSCodec; +import org.owasp.esapi.codecs.Codec; +import org.owasp.esapi.codecs.HTMLEntityCodec; +import org.owasp.esapi.codecs.JavaScriptCodec; +import org.owasp.esapi.codecs.PercentCodec; +import org.owasp.esapi.codecs.VBScriptCodec; +import org.owasp.esapi.codecs.XMLEntityCodec; +import org.owasp.esapi.codecs.JSONCodec; +import org.owasp.esapi.errors.EncodingException; +import org.owasp.esapi.errors.IntrusionException; +import org.owasp.esapi.errors.ConfigurationException; +import org.owasp.esapi.errors.NotConfiguredByDefaultException; + +import static org.owasp.esapi.PropNames.ACCEPTED_UNSAFE_METHOD_NAMES; +import static org.owasp.esapi.PropNames.ACCEPTED_UNSAFE_METHODS_JUSTIFICATION; + + +/** + * 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. + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @since June 1, 2007 + * @see org.owasp.esapi.Encoder + */ +public class DefaultEncoder implements Encoder { + + private static volatile Encoder singletonInstance; + + public static Encoder getInstance() { + if ( singletonInstance == null ) { + synchronized ( DefaultEncoder.class ) { + if ( singletonInstance == null ) { + singletonInstance = new DefaultEncoder(); + } + } + } + return singletonInstance; + } + + // Codecs + private List codecs = new ArrayList(); + private HTMLEntityCodec htmlCodec = new HTMLEntityCodec(); + private XMLEntityCodec xmlCodec = new XMLEntityCodec(); + private PercentCodec percentCodec = new PercentCodec(); + private JavaScriptCodec javaScriptCodec = new JavaScriptCodec(); + private VBScriptCodec vbScriptCodec = new VBScriptCodec(); + private CSSCodec cssCodec = new CSSCodec(); + private JSONCodec jsonCodec = new JSONCodec(); + + private final Logger logger = ESAPI.getLogger("Encoder"); + + /** + * Character sets that define characters (in addition to alphanumerics) that are + * immune from encoding in various formats + */ + private final static char[] IMMUNE_HTML = { ',', '.', '-', '_', ' ' }; + private final static char[] IMMUNE_HTMLATTR = { ',', '.', '-', '_' }; + private final static char[] IMMUNE_CSS = { '#' }; + private final static char[] IMMUNE_JAVASCRIPT = { ',', '.', '_' }; + private final static char[] IMMUNE_VBSCRIPT = { ',', '.', '_' }; + private final static char[] IMMUNE_XML = { ',', '.', '-', '_', ' ' }; + private final static char[] IMMUNE_SQL = { ' ' }; + private final static char[] IMMUNE_OS = { '-' }; + private final static char[] IMMUNE_XMLATTR = { ',', '.', '-', '_' }; + private final static char[] IMMUNE_XPATH = { ',', '.', '-', '_', ' ' }; + private final static char[] IMMUNE_JSON = { }; + + + /** + * Instantiates a new {@code DefaultEncoder} based on the property {@code Encoder.DefaultCodecList} + * from the {@code ESAPI.properties} file. + */ + private DefaultEncoder() { + this( ESAPI.securityConfiguration().getDefaultCanonicalizationCodecs() ); + } + + /** + * Instantiates a new {@code DefaultEncoder} based on the specified list of + * codec names. Unqualified codec names are assumed to belong to the package + * "org.owasp.esapi.codecs". + */ + public DefaultEncoder( List codecNames ) { + for ( String clazz : codecNames ) { + try { + if ( clazz.indexOf( '.' ) == -1 ) clazz = "org.owasp.esapi.codecs." + clazz; + codecs.add( Class.forName( clazz ).newInstance() ); + } catch ( Exception e ) { + logger.warning( Logger.EVENT_FAILURE, "Codec " + clazz + " listed in ESAPI.properties not on classpath" ); + } + } + } + + /** + * {@inheritDoc} + */ + public String canonicalize( String input ) { + if ( input == null ) { + return null; + } + + // Issue 231 - These are reverse boolean logic in the Encoder interface, so we need to invert these values - CS + return canonicalize(input, + !ESAPI.securityConfiguration().getAllowMultipleEncoding(), + !ESAPI.securityConfiguration().getAllowMixedEncoding() ); + } + + + /** + * {@inheritDoc} + */ + public String canonicalize( String input, boolean strict) { + return canonicalize(input, strict, strict); + } + + + /** + * {@inheritDoc} + */ + public String canonicalize( String input, boolean restrictMultiple, boolean restrictMixed ) { + if ( input == null ) { + return null; + } + + String working = input; + Codec codecFound = null; + int mixedCount = 1; + int foundCount = 0; + boolean clean = false; + while( !clean ) { + clean = true; + + // try each codec and keep track of which ones work + Iterator i = codecs.iterator(); + while ( i.hasNext() ) { + Codec codec = (Codec)i.next(); + String old = working; + working = codec.decode( working ); + if ( !old.equals( working ) ) { + if ( codecFound != null && codecFound != codec ) { + mixedCount++; + } + codecFound = codec; + if ( clean ) { + foundCount++; + } + clean = false; + } + } + } + + // do strict tests and handle if any mixed, multiple, nested encoding were found + if ( foundCount >= 2 && mixedCount > 1 ) { + if ( restrictMultiple || restrictMixed ) { + throw new IntrusionException( "Input validation failure", "Multiple ("+ foundCount +"x) and mixed encoding ("+ mixedCount +"x) detected in " + input ); + } else { + logger.warning( Logger.SECURITY_FAILURE, "Multiple ("+ foundCount +"x) and mixed encoding ("+ mixedCount +"x) detected in " + input ); + } + } + else if ( foundCount >= 2 ) { + if ( restrictMultiple ) { + throw new IntrusionException( "Input validation failure", "Multiple ("+ foundCount +"x) encoding detected in " + input ); + } else { + logger.warning( Logger.SECURITY_FAILURE, "Multiple ("+ foundCount +"x) encoding detected in " + input ); + } + } + else if ( mixedCount > 1 ) { + if ( restrictMixed ) { + throw new IntrusionException( "Input validation failure", "Mixed encoding ("+ mixedCount +"x) detected in " + input ); + } else { + logger.warning( Logger.SECURITY_FAILURE, "Mixed encoding ("+ mixedCount +"x) detected in " + input ); + } + } + return working; + } + + /** + * {@inheritDoc} + */ + public String encodeForHTML(String input) { + if( input == null ) { + return null; + } + return htmlCodec.encode( IMMUNE_HTML, input); + } + + /** + * {@inheritDoc} + */ + public String decodeForHTML(String input) { + + if( input == null ) { + return null; + } + return htmlCodec.decode( input); + } + + /** + * {@inheritDoc} + */ + public String encodeForHTMLAttribute(String input) { + if( input == null ) { + return null; + } + return htmlCodec.encode( IMMUNE_HTMLATTR, input); + } + + + /** + * {@inheritDoc} + */ + public String encodeForCSS(String input) { + if( input == null ) { + return null; + } + return cssCodec.encode( IMMUNE_CSS, input); + } + + + /** + * {@inheritDoc} + */ + public String encodeForJavaScript(String input) { + if( input == null ) { + return null; + } + return javaScriptCodec.encode(IMMUNE_JAVASCRIPT, input); + } + + /** + * {@inheritDoc} + */ + public String encodeForVBScript(String input) { + if( input == null ) { + return null; + } + return vbScriptCodec.encode(IMMUNE_VBSCRIPT, input); + } + + /////////////////////////////////////////////////////////////////////// + // TODO - Move this method to some utility class (where?) when we + // are ready to use it on other methods than just encodeForSQL. + // + // At that time, also move the method ESAPI.isMethodExplicityEnabled + // to the same utility class. + /** + * Utility class to throw {@code NotConfiguredByDefaultException} if the + * specified method name is not enabled by default. + * + * @param fullyQualifiedMethodName is the method name that we are checkig if + * enabled in ESAPI.properties. + * @param customAuditMsg is a audit message to log and use in exceptions. If + * this value passed in is {@code null} or the string + * "<default>", then a canned message is used to + * compose the error message. + * @param seeAlso is a string that provides additional reference for context + * such as a CVE ID, GHAS Security Advisory, or ESAPI Security Bulletin. + * @throws NotConfiguredByDefaultException if the specified method name is + * not listed in the property ESAPI.dangerouslyAllowUnsafeMethods.methodNames + * in the ESAPI.properties file. + */ + private void ensureDangerousMethodExplicitlyEnabled(String fullyQualifiedMethodName, + String customAuditMsg, + String seeAlso) { + + String auditMsg = null; + if ( customAuditMsg == null || customAuditMsg.equalsIgnoreCase("") ) { + // Special case. Compose an audit message from a canned template. + // TODO: Null / empty check for 'seeAlso'. + auditMsg = "SIEM ALERT: Method '" + fullyQualifiedMethodName + "' has been invoked despite having credible " + + "security concerns; for additional details, see " + seeAlso + "."; + } else { + auditMsg = customAuditMsg; // Use the custom audit message + } + + if ( ! ESAPI.isMethodExplicityEnabled( fullyQualifiedMethodName ) ) { + throw new NotConfiguredByDefaultException( "Method not explicitly enabled in property " + + ACCEPTED_UNSAFE_METHOD_NAMES + "; " + auditMsg ); + } else { + String justification = null; + try { + // This throws a ConfigurationException (rather than returning null if + // the property name is not found so we need to handle that. + justification = ESAPI.securityConfiguration().getStringProp( ACCEPTED_UNSAFE_METHODS_JUSTIFICATION ); + } catch ( ConfigurationException cex ) { + logger.debug( Logger.EVENT_FAILURE, "Property " + ACCEPTED_UNSAFE_METHODS_JUSTIFICATION + " not found."); + justification = "None"; + } + + if ( justification == null || justification.trim().isEmpty() ) { + justification = "None"; + } + logger.warning( Logger.SECURITY_FAILURE, auditMsg + " Provided justification: " + justification ); + } + return; + } + + + /** + * {@inheritDoc} + * + * @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 + public String encodeForSQL(Codec codec, String input) { + + // This will throw if this method is not explicitly enabled in ESAPI.properties. + ensureDangerousMethodExplicitlyEnabled( DefaultEncoder.class.getName() + ".encodeForSQL", + "", + "see CVE-2025-5878 and ESAPI Security Bulletin #13 for details" ); + + if( input == null ) { + return null; + } + return codec.encode(IMMUNE_SQL, input); + } + + /** + * {@inheritDoc} + */ + public String encodeForOS(Codec codec, String input) { + if( input == null ) { + return null; + } + return codec.encode( IMMUNE_OS, input); + } + + /** + * {@inheritDoc} + */ + public String encodeForLDAP(String input) { + return encodeForLDAP(input, true); + } + + /** + * {@inheritDoc} + */ + public String encodeForLDAP(String input, boolean encodeWildcards) { + if( input == null ) { + return null; + } + // TODO: replace with LDAP codec + StringBuilder sb = new StringBuilder(); + // According to Microsoft docs [1,2], the forward slash ('/') MUST be escaped. + // According to RFC 4515 Section 3 [3], the forward slash (and other characters) MAY be escaped. + // Since Microsoft is a MUST, escape forward slash for all implementations. Also see discussion at [4]. + // Characters above 0x7F are converted to UTF-8 and then hex encoded in the default case. + // [1] https://docs.microsoft.com/en-us/windows/win32/adsi/search-filter-syntax + // [2] https://social.technet.microsoft.com/wiki/contents/articles/5312.active-directory-characters-to-escape.aspx + // [3] https://tools.ietf.org/search/rfc4515#section-3 + // [4] https://lists.openldap.org/hyperkitty/list/openldap-technical@openldap.org/thread/3QPDDLO356ONSJM3JUKD7NMPOOIKIQ5T/ + for (int i = 0; i < input.length(); i++) { + char c = input.charAt(i); + switch (c) { + case '\\': + sb.append("\\5c"); + break; + case '/': + sb.append("\\2f"); + break; + case '*': + if (encodeWildcards) { + sb.append("\\2a"); + } + else { + sb.append(c); + } + + break; + case '(': + sb.append("\\28"); + break; + case ')': + sb.append("\\29"); + break; + case '\0': + sb.append("\\00"); + break; + default: + if (c >= 0x80) { + try { + final byte[] u = String.valueOf(c).getBytes("UTF-8"); + for (byte b : u) { + sb.append(String.format("\\%02x", b)); + } + } catch (UnsupportedEncodingException ex) { + // UTF-8 is always supported + } + } else { + sb.append(c); + } + } + } + return sb.toString(); + } + + /** + * {@inheritDoc} + */ + public String encodeForDN(String input) { + if( input == null ) { + return null; + } + // TODO: replace with DN codec + StringBuilder sb = new StringBuilder(); + if ((input.length() > 0) && ((input.charAt(0) == ' ') || (input.charAt(0) == '#'))) { + sb.append('\\'); // add the leading backslash if needed + } + // See discussion of forward slash ('/') in encodeForLDAP() + for (int i = 0; i < input.length(); i++) { + char c = input.charAt(i); + switch (c) { + case '\0': + sb.append("\\00"); + break; + case '\\': + sb.append("\\\\"); + break; + case '/': + sb.append("\\/"); + break; + case ',': + sb.append("\\,"); + break; + case '+': + sb.append("\\+"); + break; + case '"': + sb.append("\\\""); + break; + case '<': + sb.append("\\<"); + break; + case '>': + sb.append("\\>"); + break; + case ';': + sb.append("\\;"); + break; + default: + if (c >= 0x80) { + try { + final byte[] u = String.valueOf(c).getBytes("UTF-8"); + for (byte b : u) { + sb.append(String.format("\\%02x", b)); + } + } catch (UnsupportedEncodingException ex) { + // UTF-8 is always supported + } + } else { + sb.append(c); + } + } + } + // add the trailing backslash if needed + if ((input.length() > 1) && (input.charAt(input.length() - 1) == ' ')) { + sb.insert(sb.length() - 1, '\\'); + } + return sb.toString(); + } + + + /** + * {@inheritDoc} + */ + public String encodeForXPath(String input) { + if( input == null ) { + return null; + } + return htmlCodec.encode( IMMUNE_XPATH, input); + } + + /** + * {@inheritDoc} + */ + public String encodeForXML(String input) { + if( input == null ) { + return null; + } + return xmlCodec.encode( IMMUNE_XML, input); + } + + /** + * {@inheritDoc} + */ + public String encodeForXMLAttribute(String input) { + if( input == null ) { + return null; + } + return xmlCodec.encode( IMMUNE_XMLATTR, input); + } + + /** + * {@inheritDoc} + */ + public String encodeForURL(String input) throws EncodingException { + if ( input == null ) { + return null; + } + try { + return URLEncoder.encode(input, ESAPI.securityConfiguration().getCharacterEncoding()); + } catch (UnsupportedEncodingException ex) { + throw new EncodingException("Encoding failure", "Character encoding not supported", ex); + } catch (Exception e) { + throw new EncodingException("Encoding failure", "Problem URL encoding input", e); + } + } + + /** + * {@inheritDoc} + */ + public String decodeFromURL(String input) throws EncodingException { + if ( input == null ) { + return null; + } + String canonical = canonicalize(input); + try { + return URLDecoder.decode(canonical, ESAPI.securityConfiguration().getCharacterEncoding()); + } catch (UnsupportedEncodingException ex) { + throw new EncodingException("Decoding failed", "Character encoding not supported", ex); + } catch (Exception e) { + throw new EncodingException("Decoding failed", "Problem URL decoding input", e); + } + } + + /** + * {@inheritDoc} + */ + public String encodeForBase64(byte[] input, boolean wrap) { + if ( input == null ) { + return null; + } + int options = 0; + if ( !wrap ) { + options |= Base64.DONT_BREAK_LINES; + } + return Base64.encodeBytes(input, options); + } + + /** + * {@inheritDoc} + */ + public byte[] decodeFromBase64(String input) throws IOException { + if ( input == null ) { + return null; + } + return Base64.decode( input ); + } + + /** + * {@inheritDoc} + * + * This will extract each piece of a URI according to parse zone as specified in RFC-3986 section 3, + * and it will construct a canonicalized String representing a version of the URI that is safe to + * run regex against. + * + * NOTE: This method will obey the ESAPI.properties configurations for allowing + * Mixed and Multiple Encoding URLs. + * + * @param dirtyUri + * @return Canonicalized URI string. + * @throws IntrusionException + */ + public String getCanonicalizedURI(URI dirtyUri) throws IntrusionException{ + +// From RFC-3986 section 3 +// URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] +// +// hier-part = "//" authority path-abempty +// / path-absolute +// / path-rootless +// / path-empty + +// The following are two example URIs and their component parts: +// +// foo://example.com:8042/over/there?name=ferret#nose +// \_/ \______________/\_________/ \_________/ \__/ +// | | | | | +// scheme authority path query fragment +// | _____________________|__ +// / \ / \ +// urn:example:animal:ferret:nose + Map parseMap = new EnumMap(UriSegment.class); + parseMap.put(UriSegment.SCHEME, dirtyUri.getScheme()); + //authority = [ userinfo "@" ] host [ ":" port ] + parseMap.put(UriSegment.AUTHORITY, dirtyUri.getRawAuthority()); + parseMap.put(UriSegment.HOST, dirtyUri.getHost()); + //if port is undefined, it will return -1 + Integer port = new Integer(dirtyUri.getPort()); + parseMap.put(UriSegment.PORT, port == -1 ? "": port.toString()); + parseMap.put(UriSegment.PATH, dirtyUri.getRawPath()); + parseMap.put(UriSegment.QUERY, dirtyUri.getRawQuery()); + parseMap.put(UriSegment.FRAGMENT, dirtyUri.getRawFragment()); + + //Replace all the items in the map with canonicalized versions. + + Set set = parseMap.keySet(); + + SecurityConfiguration sg = ESAPI.securityConfiguration(); + boolean allowMixed = sg.getBooleanProp("Encoder.AllowMixedEncoding"); + boolean allowMultiple = sg.getBooleanProp("Encoder.AllowMultipleEncoding"); + for(UriSegment seg: set){ + String value = ""; + //In the case of a uri query, we need to break up and canonicalize the internal parts of the query. + if(seg == UriSegment.QUERY && null != parseMap.get(seg)){ + StringBuilder qBuilder = new StringBuilder(); + try { + Map> canonicalizedMap = this.splitQuery(dirtyUri); + Set>> query = canonicalizedMap.entrySet(); + Iterator>> i = query.iterator(); + while(i.hasNext()){ + Entry> e = i.next(); + String key = e.getKey(); + String qVal = ""; + List list = e.getValue(); + if(!list.isEmpty()){ + qVal = list.get(0); + } + qBuilder.append(key) + .append("=") + .append(qVal); + + if(i.hasNext()){ + qBuilder.append("&"); + } + } + value = qBuilder.toString(); + } catch (UnsupportedEncodingException e) { + logger.debug(Logger.EVENT_FAILURE, "decoding error when parsing [" + dirtyUri.toString() + "]"); + } + } else { + String extractedInput = parseMap.get(seg); + value = canonicalize(extractedInput, allowMultiple, allowMixed); + value = value == null ? "" : value; + } + //Check if the port is -1, if it is, omit it from the output. + if(seg == UriSegment.PORT){ + if("-1" == parseMap.get(seg)){ + value = ""; + } + } + parseMap.put(seg, value ); + } + + return buildUrl(parseMap); + } + + /** + * All the parts should be canonicalized by this point. This is straightforward assembly. + * + * @param parseMap The parts of the URL to put back together. + * @return The canonicalized URL. + */ + protected String buildUrl(Map parseMap){ + StringBuilder sb = new StringBuilder(); + boolean schemePresent = parseMap.get(UriSegment.SCHEME).equals("") ? false : true; + + if(schemePresent) { + sb.append(parseMap.get(UriSegment.SCHEME)) + .append("://"); + } + + //can't use SCHEMESPECIFICPART for this, because we need to canonicalize all the parts of the query. + //USERINFO is also deprecated. So we technically have more than we need. + sb.append(parseMap.get(UriSegment.AUTHORITY) == null || parseMap.get(UriSegment.AUTHORITY).equals("") ? "" : parseMap.get(UriSegment.AUTHORITY)) + .append(parseMap.get(UriSegment.PATH) == null || parseMap.get(UriSegment.PATH).equals("") ? "" : parseMap.get(UriSegment.PATH)) + .append(parseMap.get(UriSegment.QUERY) == null || parseMap.get(UriSegment.QUERY).equals("") + ? "" : "?" + parseMap.get(UriSegment.QUERY)) + .append((parseMap.get(UriSegment.FRAGMENT) == null) || parseMap.get(UriSegment.FRAGMENT).equals("") + ? "": "#" + parseMap.get(UriSegment.FRAGMENT)) + ; + return sb.toString(); + } + + public enum UriSegment { + AUTHORITY, SCHEME, SCHEMSPECIFICPART, USERINFO, HOST, PORT, PATH, QUERY, FRAGMENT + } + + + /** + * The meat of this method was taken from StackOverflow: http://stackoverflow.com/a/13592567/557153 + * It has been modified to return a canonicalized key and value pairing. + * + * @param uri The URI to analyze. + * @return a map of canonicalized query parameters. + * @throws UnsupportedEncodingException + */ + public Map> splitQuery(URI uri) throws UnsupportedEncodingException { + final Map> query_pairs = new LinkedHashMap>(); + final String[] pairs = uri.getQuery().split("&"); + for (String pair : pairs) { + final int idx = pair.indexOf("="); + final String key = idx > 0 ? canonicalize(pair.substring(0, idx)) : pair; + if (!query_pairs.containsKey(key)) { + query_pairs.put(key, new LinkedList()); + } + final String value = idx > 0 && pair.length() > idx + 1 ? URLDecoder.decode(pair.substring(idx + 1), "UTF-8") : null; + query_pairs.get(key).add(canonicalize(value)); + } + return query_pairs; + } + + /** + * {@inheritDoc} + */ + public String encodeForJSON(String input) { + if( input == null ) { + return null; + } + return jsonCodec.encode(IMMUNE_JSON, input); + } + + /** + * {@inheritDoc} + */ + public String decodeFromJSON(String input) { + if( input == null ) { + return null; + } + return jsonCodec.decode(input); + } + +} diff --git a/src/main/java/org/owasp/esapi/reference/DefaultExecutor.java b/src/main/java/org/owasp/esapi/reference/DefaultExecutor.java new file mode 100644 index 000000000..619e633ec --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/DefaultExecutor.java @@ -0,0 +1,234 @@ +/** + * 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.reference; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.List; +import java.util.Map; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.ExecuteResult; +import org.owasp.esapi.Executor; +import org.owasp.esapi.Logger; +import org.owasp.esapi.codecs.Codec; +import org.owasp.esapi.codecs.UnixCodec; +import org.owasp.esapi.codecs.WindowsCodec; +import org.owasp.esapi.errors.ExecutorException; + +/** + * 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 codec dependent, but will usually only include alphanumeric, forward-slash, and dash.

+ * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @since June 1, 2007 + * @see org.owasp.esapi.Executor + */ +public class DefaultExecutor implements org.owasp.esapi.Executor { + private static volatile Executor singletonInstance; + + public static Executor getInstance() { + if ( singletonInstance == null ) { + synchronized ( DefaultExecutor.class ) { + if ( singletonInstance == null ) { + singletonInstance = new DefaultExecutor(); + } + } + } + return singletonInstance; + } + + /** The logger. */ + private final Logger logger = ESAPI.getLogger("Executor"); + private Codec codec = null; + //private final int MAX_SYSTEM_COMMAND_LENGTH = 2500; + + + /** + * Instantiate a new Executor + */ + private DefaultExecutor() { + if ( System.getProperty("os.name").indexOf("Windows") != -1 ) { + logger.warning( Logger.SECURITY_SUCCESS, "Using WindowsCodec for Executor. If this is not running on Windows this could allow injection" ); + codec = new WindowsCodec(); + } else { + logger.warning( Logger.SECURITY_SUCCESS, "Using UnixCodec for Executor. If this is not running on Unix this could allow injection" ); + codec = new UnixCodec(); + } + } + + /** + * {@inheritDoc} + */ + public ExecuteResult executeSystemCommand(File executable, List params) throws ExecutorException { + File workdir = ESAPI.securityConfiguration().getWorkingDirectory(); + boolean logParams = false; + boolean redirectErrorStream = false; + return executeSystemCommand( executable, params, workdir, codec, logParams, redirectErrorStream ); + } + + /** + * {@inheritDoc} + * + * The reference implementation sets the work directory, escapes the parameters as per the Codec in use, + * and then executes the command without using concatenation. The exact, absolute, canonical path of each + * executable must be listed as an approved executable in the ESAPI properties. The executable must also + * exist on the disk. All failures will be logged, along with parameters if specified. Set the logParams to false if + * you are going to invoke this interface with confidential information. + */ + public ExecuteResult executeSystemCommand(File executable, List params, File workdir, Codec codec, boolean logParams, boolean redirectErrorStream ) throws ExecutorException { + try { + // executable must exist + if (!executable.exists()) { + throw new ExecutorException("Execution failure", "No such executable: " + executable); + } + + // executable must use canonical path + if ( !executable.isAbsolute() ) { + throw new ExecutorException("Execution failure", "Attempt to invoke an executable using a non-absolute path: " + executable); + } + + // executable must use canonical path + if ( !executable.getPath().equals( executable.getCanonicalPath() ) ) { + throw new ExecutorException("Execution failure", "Attempt to invoke an executable using a non-canonical path: " + executable); + } + + // exact, absolute, canonical path to executable must be listed in ESAPI configuration + List approved = ESAPI.securityConfiguration().getAllowedExecutables(); + if (!approved.contains(executable.getPath())) { + throw new ExecutorException("Execution failure", "Attempt to invoke executable that is not listed as an approved executable in ESAPI configuration: " + executable.getPath() + " not listed in " + approved ); + } + + // escape any special characters in the parameters + for ( int i = 0; i < params.size(); i++ ) { + String param = (String)params.get(i); + params.set( i, ESAPI.encoder().encodeForOS(codec, param)); + } + + // working directory must exist + if (!workdir.exists()) { + throw new ExecutorException("Execution failure", "No such working directory for running executable: " + workdir.getPath()); + } + + // set the command into the list and create command array + params.add(0, executable.getCanonicalPath()); + + // Legacy - this is how to implement in Java 1.4 + // String[] command = (String[])params.toArray( new String[0] ); + // Process process = Runtime.getRuntime().exec(command, new String[0], workdir); + + // The following is host to implement in Java 1.5+ + ProcessBuilder pb = new ProcessBuilder(params); + Map env = pb.environment(); + env.clear(); // Security check - clear environment variables! + pb.directory(workdir); + pb.redirectErrorStream(redirectErrorStream); + + if ( logParams ) { + logger.debug(Logger.SECURITY_SUCCESS, "Initiating executable: " + executable + " " + params + " in " + workdir); + } else { + logger.debug(Logger.SECURITY_SUCCESS, "Initiating executable: " + executable + " [sensitive parameters obscured] in " + workdir); + } + + final StringBuilder outputBuffer = new StringBuilder(); + final StringBuilder errorsBuffer = new StringBuilder(); + final Process process = pb.start(); + try { + ReadThread errorReader; + if (!redirectErrorStream) { + errorReader = new ReadThread(process.getErrorStream(), errorsBuffer); + errorReader.start(); + } else { + errorReader = null; + } + readStream( process.getInputStream(), outputBuffer ); + if (errorReader != null) { + errorReader.join(); + if (errorReader.exception != null) { + throw errorReader.exception; + } + } + process.waitFor(); + } catch (Throwable e) { + process.destroy(); + throw new ExecutorException("Execution failure", "Exception thrown during execution of system command: " + e.getMessage(), e); + } + + String output = outputBuffer.toString(); + String errors = errorsBuffer.toString(); + int exitValue = process.exitValue(); + if ( errors != null && errors.length() > 0 ) { + String logErrors = errors; + final int MAX_LEN = 256; + if (logErrors.length() > MAX_LEN) { + logErrors = logErrors.substring(0, MAX_LEN) + "(truncated at "+MAX_LEN+" characters)"; + } + logger.warning( Logger.SECURITY_SUCCESS, "Error during system command: " + logErrors ); + } + if ( exitValue != 0 ) { + logger.warning( Logger.EVENT_FAILURE, "System command exited with non-zero status: " + exitValue ); + } + + logger.debug(Logger.SECURITY_SUCCESS, "System command complete"); + return new ExecuteResult(exitValue, output, errors); + } catch (IOException e) { + throw new ExecutorException("Execution failure", "Exception thrown during execution of system command: " + e.getMessage(), e); + } + } + + /** + * readStream reads lines from an input stream and returns all of them in a single string + * + * @param is + * input stream to read from + * @throws IOException + */ + private static void readStream( InputStream is, StringBuilder sb ) throws IOException { + InputStreamReader isr = new InputStreamReader(is); + BufferedReader br = new BufferedReader(isr); + String line; + while ((line = br.readLine()) != null) { + sb.append(line).append('\n'); + } + } + + private static class ReadThread extends Thread { + volatile IOException exception; + private final InputStream stream; + private final StringBuilder buffer; + + ReadThread(InputStream stream, StringBuilder buffer) { + this.stream = stream; + this.buffer = buffer; + } + + @Override + public void run() { + try { + readStream(stream, buffer); + } catch (IOException e) { + exception = e; + } + } + + } + +} diff --git a/src/main/java/org/owasp/esapi/reference/DefaultHTTPUtilities.java b/src/main/java/org/owasp/esapi/reference/DefaultHTTPUtilities.java new file mode 100644 index 000000000..2dabec23c --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/DefaultHTTPUtilities.java @@ -0,0 +1,1179 @@ +/** + * 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.reference; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import java.util.concurrent.ConcurrentHashMap; + +import javax.servlet.RequestDispatcher; +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 org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.ProgressListener; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.commons.fileupload.servlet.ServletFileUpload; +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.HTTPUtilities; +import org.owasp.esapi.Logger; +import org.owasp.esapi.PropNames; +import org.owasp.esapi.SecurityConfiguration; +import org.owasp.esapi.StringUtilities; +import org.owasp.esapi.User; +import org.owasp.esapi.ValidationErrorList; +import org.owasp.esapi.codecs.Hex; +import org.owasp.esapi.crypto.CipherText; +import org.owasp.esapi.crypto.PlainText; +import org.owasp.esapi.errors.AccessControlException; +import org.owasp.esapi.errors.AuthenticationException; +import org.owasp.esapi.errors.ConfigurationException; +import org.owasp.esapi.errors.EncodingException; +import org.owasp.esapi.errors.EncryptionException; +import org.owasp.esapi.errors.IntegrityException; +import org.owasp.esapi.errors.IntrusionException; +import org.owasp.esapi.errors.ValidationException; +import org.owasp.esapi.errors.ValidationUploadException; + +/** + * 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, some methods use 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. In either case, you *must* call ESAPI.clearCurrent() to clear threadlocal + * variables before the thread is reused. The advantages of having identity everywhere + * outweigh the disadvantages of this approach. + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @since June 1, 2007 + * @see org.owasp.esapi.HTTPUtilities + */ +public class DefaultHTTPUtilities implements org.owasp.esapi.HTTPUtilities { + private static volatile HTTPUtilities instance = null; + + // Apache Commons FileUpload property for enabling / disabling Java deserialization via file uploads. + // ESAPI will save current value, set it to "false", and then restore value before returning. GitHub issue #417. + private static String DISKFILEITEM_SERIALIZABLE = "org.apache.commons.fileupload.disk.DiskFileItem.serializable"; + + public static HTTPUtilities getInstance() { + if ( instance == null ) { + synchronized ( DefaultHTTPUtilities.class ) { + if ( instance == null ) { + instance = new DefaultHTTPUtilities(); + } + } + } + return instance; + } + + /** + * Defines the ThreadLocalRequest to store the current request for this thread. + */ + private class ThreadLocalRequest extends InheritableThreadLocal { + + public HttpServletRequest getRequest() { + return super.get(); + } + + public HttpServletRequest initialValue() { + return null; + } + + public void setRequest(HttpServletRequest newRequest) { + super.set(newRequest); + } + } + + /** + * Defines the ThreadLocalResponse to store the current response for this thread. + */ + private class ThreadLocalResponse extends InheritableThreadLocal { + + public HttpServletResponse getResponse() { + return super.get(); + } + + public HttpServletResponse initialValue() { + return null; + } + + public void setResponse(HttpServletResponse newResponse) { + super.set(newResponse); + } + } + + /** The logger. */ + private final Logger logger = ESAPI.getLogger("HTTPUtilities"); + + /** The max bytes. */ + static final int maxBytes = ESAPI.securityConfiguration().getAllowedFileUploadSize(); + + /** The max # of files per request. */ + static int maxFiles = 20; // Same as default in configuration/esapi/ESAPI.properties + + static boolean fileUploadAllowAnonymousUsers = true; + + static { + // OPENISSUE - Not sure if we should log this. I can throw because the + // property is not set in ESAPI.properties, but it can also throw + // because ESAPI.properties can't be found. If the latter is the case, + // then trying to log it would cause another ConfigurationException to + // be thrown while trying do the logging making the exception stack + // traces even more obtuse. And I don't want to spend then next 5 years + // answering Stack Overflow questions about that. + try { + maxFiles = ESAPI.securityConfiguration().getIntProp( PropNames.MAX_UPLOAD_FILE_COUNT ); + } catch ( ConfigurationException ex ) { + // TODO: Figure out what we want to do log this. See OPENISSUE, above. + System.err.println("WARNING: Caught exception looking for property " + PropNames.MAX_UPLOAD_FILE_COUNT + + " in ESAPI.properties. Using hard-coded default of " + maxFiles + + "; exception was: " + ex); + } + try { + fileUploadAllowAnonymousUsers = ESAPI.securityConfiguration().getBooleanProp( PropNames.FILEUPLOAD_ALLOW_ANONYMOUS_USERS ); + } catch ( ConfigurationException ex ) { + // This likely will be the normal case (because ESAPI clients seldom update + // their ESAPI.properties file from release to release. Therefore, I am + // going to ignore it, and we silently go with the default of 'false'. + ; // Intentionally ignore! + } + } + + /* + * The currentRequest ThreadLocal variable is used to make the currentRequest available to any call in any part of an + * application. This enables API's for actions that require the request to be much simpler. For example, the logout() + * method in the Authenticator class requires the currentRequest to get the session in order to invalidate it. + */ + private ThreadLocalRequest currentRequest = new ThreadLocalRequest(); + + /* + * The currentResponse ThreadLocal variable is used to make the currentResponse available to any call in any part of an + * application. This enables API's for actions that require the response to be much simpler. For example, the logout() + * method in the Authenticator class requires the currentResponse to kill the Session ID cookie. + */ + private ThreadLocalResponse currentResponse = new ThreadLocalResponse(); + + + + /** + * No arg constructor. + */ + public DefaultHTTPUtilities() { // Public CTOR for singletons. SMH. Sigh. + } + + + /** + * {@inheritDoc} + * This implementation uses a custom "set-cookie" header rather than Java's + * cookie interface which doesn't allow the use of HttpOnly. Configure the + * HttpOnly and Secure settings in ESAPI.properties. + */ + public void addCookie( Cookie cookie ) { + addCookie( getCurrentResponse(), cookie ); + } + + /** + * {@inheritDoc} + * This implementation uses a custom "set-cookie" header rather than Java's + * cookie interface which doesn't allow the use of HttpOnly. Configure the + * HttpOnly and Secure settings in ESAPI.properties. + */ + public void addCookie(HttpServletResponse response, Cookie cookie) { + String name = cookie.getName(); + String value = cookie.getValue(); + int maxAge = cookie.getMaxAge(); + String domain = cookie.getDomain(); + String path = cookie.getPath(); + boolean secure = cookie.getSecure(); + + // validate the name and value + ValidationErrorList errors = new ValidationErrorList(); + SecurityConfiguration sc = ESAPI.securityConfiguration(); + String cookieName = ESAPI.validator().getValidInput("cookie name", name, "HTTPCookieName", sc.getIntProp("HttpUtilities.MaxHeaderNameSize"), false, errors); + String cookieValue = ESAPI.validator().getValidInput("cookie value", value, "HTTPCookieValue", sc.getIntProp("HttpUtilities.MaxHeaderValueSize"), false, errors); + + // if there are no errors, then set the cookie either with a header or normally + if (errors.size() == 0) { + if ( ESAPI.securityConfiguration().getForceHttpOnlyCookies() ) { + String header = createCookieHeader(cookieName, cookieValue, maxAge, domain, path, secure); + addHeader(response, "Set-Cookie", header); + } else { + // Issue 23 - If the ESAPI Configuration is set to force secure cookies, force the secure flag on the cookie before setting it + cookie.setSecure( secure || ESAPI.securityConfiguration().getForceSecureCookies() ); + response.addCookie(cookie); + } + return; + } + logger.warning(Logger.SECURITY_FAILURE, "Attempt to add unsafe data to cookie (skip mode). Skipping cookie and continuing."); + } + + + + /** + * {@inheritDoc} + */ + public String addCSRFToken(String href) { + User user = ESAPI.authenticator().getCurrentUser(); + if (user.isAnonymous()) { + return href; + } + + // if there are already parameters append with &, otherwise append with ? + String token = CSRF_TOKEN_NAME + "=" + user.getCSRFToken(); + return href.indexOf( '?') != -1 ? href + "&" + token : href + "?" + token; + } + + /** + * {@inheritDoc} + */ + public void addHeader(String name, String value) { + addHeader( getCurrentResponse(), name, value ); + } + + /** + * {@inheritDoc} + */ + public void addHeader(HttpServletResponse response, String name, String value) { + SecurityConfiguration sc = ESAPI.securityConfiguration(); + try { + String strippedName = StringUtilities.replaceLinearWhiteSpace(name); + String strippedValue = StringUtilities.replaceLinearWhiteSpace(value); + String safeName = ESAPI.validator().getValidInput("addHeader", strippedName, "HTTPHeaderName", sc.getIntProp("HttpUtilities.MaxHeaderNameSize"), false); + String safeValue = ESAPI.validator().getValidInput("addHeader", strippedValue, "HTTPHeaderValue", sc.getIntProp("HttpUtilities.MaxHeaderValueSize"), false); + response.addHeader(safeName, safeValue); + } catch (ValidationException e) { + logger.warning(Logger.SECURITY_FAILURE, "Attempt to add invalid header denied", e); + } + } + + /** + * {@inheritDoc} + */ + public void assertSecureChannel() throws AccessControlException { + assertSecureChannel( getCurrentRequest() ); + } + + /** + * {@inheritDoc} + * + * This implementation ignores the built-in isSecure() method + * and uses the URL to determine if the request was transmitted over SSL. + * This is because SSL may have been terminated somewhere outside the + * container. + */ + public void assertSecureChannel(HttpServletRequest request) throws AccessControlException { + if ( request == null ) { + throw new AccessControlException( "Insecure request received", "HTTP request was null" ); + } + StringBuffer sb = request.getRequestURL(); + if ( sb == null ) { + throw new AccessControlException( "Insecure request received", "HTTP request URL was null" ); + } + String url = sb.toString(); + if ( !url.startsWith( "https" ) ) { + throw new AccessControlException( "Insecure request received", "HTTP request did not use SSL" ); + } + } + + /** + * {@inheritDoc} + */ + public void assertSecureRequest() throws AccessControlException { + assertSecureRequest( getCurrentRequest() ); + } + + /** + * {@inheritDoc} + */ + public void assertSecureRequest(HttpServletRequest request) throws AccessControlException { + assertSecureChannel( request ); + String receivedMethod = request.getMethod(); + String requiredMethod = "POST"; + if ( !receivedMethod.equals( requiredMethod ) ) { + throw new AccessControlException( "Insecure request received", "Received request using " + receivedMethod + " when only " + requiredMethod + " is allowed" ); + } + } + + /** + * {@inheritDoc} + */ + public HttpSession changeSessionIdentifier() throws AuthenticationException { + return changeSessionIdentifier( getCurrentRequest() ); + } + + /** + * {@inheritDoc} + */ + public HttpSession changeSessionIdentifier(HttpServletRequest request) throws AuthenticationException { + + // get the current session + HttpSession oldSession = request.getSession(); + + // make a copy of the session content + Map temp = new ConcurrentHashMap(); + Enumeration e = oldSession.getAttributeNames(); + while (e != null && e.hasMoreElements()) { + String name = (String) e.nextElement(); + Object value = oldSession.getAttribute(name); + temp.put(name, value); + } + + // kill the old session and create a new one + oldSession.invalidate(); + HttpSession newSession = request.getSession(); + User user = ESAPI.authenticator().getCurrentUser(); + user.addSession( newSession ); + user.removeSession( oldSession ); + + // copy back the session content + for (Map.Entry stringObjectEntry : temp.entrySet()) + { + newSession.setAttribute(stringObjectEntry.getKey(), stringObjectEntry.getValue()); + } + return newSession; + } + + /** + * {@inheritDoc} + */ + public void clearCurrent() { + currentRequest.set(null); + currentResponse.set(null); + } + + private String createCookieHeader(String name, String value, int maxAge, String domain, String path, boolean secure) { + // create the special cookie header instead of creating a Java cookie + // Set-Cookie:=[; =][; expires=][; + // domain=][; path=][; secure][;HttpOnly] + String header = name + "=" + value; + if (maxAge >= 0) { + header += "; Max-Age=" + maxAge; + } + if (domain != null) { + header += "; Domain=" + domain; + } + if (path != null) { + header += "; Path=" + path; + } + if ( secure || ESAPI.securityConfiguration().getForceSecureCookies() ) { + header += "; Secure"; + } + if ( ESAPI.securityConfiguration().getForceHttpOnlyCookies() ) { + header += "; HttpOnly"; + } + return header; + } + + /** + * {@inheritDoc} + */ + public String decryptHiddenField(String encrypted) { + try { + return decryptString(encrypted); + } catch( EncryptionException e ) { + throw new IntrusionException("Invalid request","Tampering detected. Hidden field data did not decrypt properly.", e); + } + } + + /** + * {@inheritDoc} + */ + public Map decryptQueryString(String encrypted) throws EncryptionException { + String plaintext = decryptString(encrypted); + return queryToMap(plaintext); + } + + /** + * {@inheritDoc} + */ + public Map decryptStateFromCookie() throws EncryptionException { + return decryptStateFromCookie( getCurrentRequest() ); + } + + /** + * {@inheritDoc} + * + * @param request + */ + public Map decryptStateFromCookie(HttpServletRequest request) throws EncryptionException { + try { + String encrypted = getCookie( request, ESAPI_STATE ); + if ( encrypted == null ) return new HashMap(); + String plaintext = decryptString(encrypted); + return queryToMap( plaintext ); + } catch( ValidationException e ) { + return null; + } + } + + /** + * {@inheritDoc} + */ + public String encryptHiddenField(String value) throws EncryptionException { + return encryptString(value); + } + + /** + * {@inheritDoc} + */ + public String encryptQueryString(String query) throws EncryptionException { + return encryptString(query); + } + + /** + * {@inheritDoc} + */ + public void encryptStateInCookie(HttpServletResponse response, Map cleartext) throws EncryptionException { + StringBuilder sb = new StringBuilder(); + Iterator i = cleartext.entrySet().iterator(); + while ( i.hasNext() ) { + try { + Map.Entry entry = (Map.Entry)i.next(); + + // What do these need to be URL encoded? They are encrypted! + String name = ESAPI.encoder().encodeForURL( entry.getKey().toString() ); + String value = ESAPI.encoder().encodeForURL( entry.getValue().toString() ); + sb.append(name).append("=").append(value); + if ( i.hasNext() ) sb.append( "&" ); + } catch( EncodingException e ) { + logger.error(Logger.SECURITY_FAILURE, "Problem encrypting state in cookie - skipping entry", e ); + } + } + + String encrypted = encryptString(sb.toString()); + + if ( encrypted.length() > (MAX_COOKIE_LEN ) ) { + logger.error(Logger.SECURITY_FAILURE, "Problem encrypting state in cookie - skipping entry"); + throw new EncryptionException("Encryption failure", "Encrypted cookie state of " + encrypted.length() + " longer than allowed " + MAX_COOKIE_LEN ); + } + + Cookie cookie = new Cookie( ESAPI_STATE, encrypted ); + addCookie( response, cookie ); + } + + /** + * {@inheritDoc} + */ + public void encryptStateInCookie( Map cleartext ) throws EncryptionException { + encryptStateInCookie( getCurrentResponse(), cleartext ); + } + + + /** + * {@inheritDoc} + */ + public String getCookie( HttpServletRequest request, String name ) throws ValidationException { + Cookie c = getFirstCookie( request, name ); + SecurityConfiguration sc = ESAPI.securityConfiguration(); + if ( c == null ) return null; + String value = c.getValue(); + return ESAPI.validator().getValidInput("HTTP cookie value: " + value, value, "HTTPCookieValue", sc.getIntProp("HttpUtilities.MaxHeaderValueSize"), false); + } + + /** + * {@inheritDoc} + */ + public String getCookie( String name ) throws ValidationException { + return getCookie( getCurrentRequest(), name ); + } + + /** + * {@inheritDoc} + */ + public String getCSRFToken() { + User user = ESAPI.authenticator().getCurrentUser(); + if (user == null) return null; + return user.getCSRFToken(); + } + + + /** + * {@inheritDoc} + */ + public HttpServletRequest getCurrentRequest() { + return currentRequest.getRequest(); + } + + + /** + * {@inheritDoc} + */ + public HttpServletResponse getCurrentResponse() { + return currentResponse.getResponse(); + } + + /** + * {@inheritDoc} + */ + public List getFileUploads() throws ValidationException { + return getFileUploads( getCurrentRequest(), ESAPI.securityConfiguration().getUploadDirectory(), ESAPI.securityConfiguration().getAllowedFileExtensions() ); + } + + /** + * {@inheritDoc} + */ + public List getFileUploads(HttpServletRequest request) throws ValidationException { + return getFileUploads(request, ESAPI.securityConfiguration().getUploadDirectory(), ESAPI.securityConfiguration().getAllowedFileExtensions()); + } + + /** + * {@inheritDoc} + */ + public List getFileUploads(HttpServletRequest request, File finalDir ) throws ValidationException { + return getFileUploads(request, finalDir, ESAPI.securityConfiguration().getAllowedFileExtensions()); + } + + /** + * {@inheritDoc} + */ + public List getFileUploads(HttpServletRequest request, File finalDir, List allowedExtensions) throws ValidationException { + File tempDir = ESAPI.securityConfiguration().getUploadTempDirectory(); + if ( !tempDir.exists() ) { + if ( !tempDir.mkdirs() ) throw new ValidationUploadException( "Upload failed", "Could not create temp directory: " + tempDir.getAbsolutePath() ); + } + + if( finalDir != null){ + if ( !finalDir.exists() ) { + if ( !finalDir.mkdirs() ) throw new ValidationUploadException( "Upload failed", "Could not create final upload directory: " + finalDir.getAbsolutePath() ); + } + } + else { + if ( !ESAPI.securityConfiguration().getUploadDirectory().exists()) { + if ( !ESAPI.securityConfiguration().getUploadDirectory().mkdirs() ) throw new ValidationUploadException( "Upload failed", "Could not create final upload directory: " + ESAPI.securityConfiguration().getUploadDirectory().getAbsolutePath() ); + } + finalDir = ESAPI.securityConfiguration().getUploadDirectory(); + } + + // Check if this user should be blocked from file upload access. See allowUserFileUploadAccess() and comments + // around 'HttpUtilities.FileUploadAllowAnonymousUser' in ESAPI.properties file for details. + if ( ! allowUserFileUploadAccess() ) { + final String authZErrorMsg = "Upload failed. Anonymous user disallowed by ESAPI property " + + "'HttpUtilities.FileUploadAllowAnonymousUser'; attempted file upload blocked."; + logger.warning(Logger.SECURITY_FAILURE, authZErrorMsg); + throw new java.security.AccessControlException( authZErrorMsg ); + } + + + List newFiles = new ArrayList(); + String dfiPrevValue = "false"; // Fail safely in case of Java Security Manager & weird security policy + try { + dfiPrevValue = System.getProperty(DISKFILEITEM_SERIALIZABLE); + System.setProperty(DISKFILEITEM_SERIALIZABLE, "false"); + final HttpSession session = request.getSession(false); + if (!ServletFileUpload.isMultipartContent(request)) { + throw new ValidationUploadException("Upload failed", "Not a multipart request"); + } + + // this factory will store ALL files in the temp directory, regardless of size + DiskFileItemFactory factory = new DiskFileItemFactory(0, tempDir); + ServletFileUpload upload = new ServletFileUpload(factory); + upload.setSizeMax(maxBytes); + upload.setFileCountMax(maxFiles); // Required to address CVE-2023-24998. + + // Create a progress listener + ProgressListener progressListener = new ProgressListener() { + private long megaBytes = -1; + private long progress = 0; + + public void update(long pBytesRead, long pContentLength, int pItems) { + if (pItems == 0) + return; + long mBytes = pBytesRead / 1000000; + if (megaBytes == mBytes) + return; + megaBytes = mBytes; + progress = (long) (((double) pBytesRead / (double) pContentLength) * 100); + if ( session != null ) { + session.setAttribute("progress", Long.toString(progress)); + } + // logger.logSuccess(Logger.SECURITY, " Item " + pItems + " (" + progress + "% of " + pContentLength + " bytes]"); + } + }; + upload.setProgressListener(progressListener); + + List items = upload.parseRequest(request); + for (FileItem item : items) + { + if (!item.isFormField() && item.getName() != null && !(item.getName().equals(""))) + { + String[] fparts = item.getName().split("[\\/\\\\]"); + String filename = fparts[fparts.length - 1]; + + if (!ESAPI.validator().isValidFileName("upload", filename, allowedExtensions, false)) + { + throw new ValidationUploadException("Upload only simple filenames with the following extensions " + allowedExtensions, "Upload failed isValidFileName check"); + } + + logger.info(Logger.SECURITY_SUCCESS, "File upload requested: " + filename); + File f = new File(finalDir, filename); + if (f.exists()) + { + String[] parts = filename.split("\\/."); + String extension = ""; + if (parts.length > 1) + { + extension = parts[parts.length - 1]; + } + String filenm = filename.substring(0, filename.length() - extension.length()); + f = File.createTempFile(filenm, "." + extension, finalDir); + } + + item.write(f); + newFiles.add(f); + // delete temporary file + item.delete(); + logger.fatal(Logger.SECURITY_SUCCESS, "File successfully uploaded: " + f); + if (session != null) + { + session.setAttribute("progress", Long.toString(0)); + } + } + } + } catch (Exception e) { + if (e instanceof ValidationUploadException) { + throw (ValidationException)e; + } + throw new ValidationUploadException("Upload failure", "Problem during upload:" + e.getMessage(), e); + } + finally { + if ( dfiPrevValue != null ) { + System.setProperty(DISKFILEITEM_SERIALIZABLE, dfiPrevValue); + } + } + return Collections.synchronizedList(newFiles); + } + + + + /** + * Utility to return the first cookie matching the provided name. + * @param request + * @param name + */ + private Cookie getFirstCookie(HttpServletRequest request, String name) { + Cookie[] cookies = request.getCookies(); + if (cookies != null) { + for (Cookie cookie : cookies) + { + if (cookie.getName().equals(name)) + { + return cookie; + } + } + } + return null; + } + + /** + * {@inheritDoc} + */ + public String getHeader( HttpServletRequest request, String name ) throws ValidationException { + SecurityConfiguration sc = ESAPI.securityConfiguration(); + String value = request.getHeader(name); + return ESAPI.validator().getValidInput("HTTP header value: " + value, value, "HTTPHeaderValue", sc.getIntProp("HttpUtilities.MaxHeaderValueSize"), false); + } + + + /** + * {@inheritDoc} + */ + public String getHeader( String name ) throws ValidationException { + return getHeader( getCurrentRequest(), name ); + } + + + /** + * {@inheritDoc} + */ + public String getParameter( HttpServletRequest request, String name ) throws ValidationException { + String value = request.getParameter(name); + return ESAPI.validator().getValidInput("HTTP parameter value: " + value, value, "HTTPParameterValue", 2000, true); + } + + /** + * {@inheritDoc} + */ + public String getParameter( String name ) throws ValidationException { + return getParameter( getCurrentRequest(), name ); + } + + /** + * {@inheritDoc} + */ + public void killAllCookies() { + killAllCookies( getCurrentRequest(), getCurrentResponse() ); + } + + /** + * {@inheritDoc} + * + * @param request + * @param response + */ + public void killAllCookies(HttpServletRequest request, HttpServletResponse response) { + Cookie[] cookies = request.getCookies(); + if (cookies != null) { + for (Cookie cookie : cookies) + { + killCookie(request, response, cookie.getName()); + } + } + } + + + /** + * {@inheritDoc} + * + * @param request + * @param response + * @param name + */ + public void killCookie(HttpServletRequest request, HttpServletResponse response, String name) { + String path = "/"; + String domain=""; + Cookie cookie = getFirstCookie(request, name); + if ( cookie != null ) { + path = cookie.getPath(); + domain = cookie.getDomain(); + } + Cookie deleter = new Cookie( name, "deleted" ); + deleter.setMaxAge( 0 ); + if ( domain != null ) deleter.setDomain( domain ); + if ( path != null ) deleter.setPath( path ); + response.addCookie( deleter ); + } + + + /** + * {@inheritDoc} + */ + public void killCookie( String name ) { + killCookie( getCurrentRequest(), getCurrentResponse(), name ); + } + + + /** + * {@inheritDoc} + */ + public void logHTTPRequest() { + logHTTPRequest( getCurrentRequest(), logger, null ); + } + + /** + * {@inheritDoc} + */ + public void logHTTPRequest(HttpServletRequest request, Logger logger) { + logHTTPRequest( request, logger, null ); + } + + /** + * 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. + * + * + * @param request + */ + public void logHTTPRequest(HttpServletRequest request, Logger logger, List parameterNamesToObfuscate) { + StringBuilder params = new StringBuilder(); + Iterator i = request.getParameterMap().keySet().iterator(); + while (i.hasNext()) { + String key = (String) i.next(); + String[] value = request.getParameterMap().get(key); + for (int j = 0; j < value.length; j++) { + params.append(key).append("="); + if (parameterNamesToObfuscate != null && parameterNamesToObfuscate.contains(key)) { + params.append("********"); + } else { + params.append(value[j]); + } + if (j < value.length - 1) { + params.append("&"); + } + } + if (i.hasNext()) + params.append("&"); + } + Cookie[] cookies = request.getCookies(); + if ( cookies != null ) { + for (Cookie cooky : cookies) + { + if (!cooky.getName().equals(ESAPI.securityConfiguration().getHttpSessionIdName())) + { + params.append("+").append(cooky.getName()).append("=").append(cooky.getValue()); + } + } + } + String msg = request.getMethod() + " " + request.getRequestURL() + (params.length() > 0 ? "?" + params : ""); + logger.info(Logger.SECURITY_SUCCESS, msg); + } + + private Map queryToMap(String query) { + TreeMap map = new TreeMap(); + String[] parts = query.split("&"); + for (String part : parts) + { + try + { + String[] nvpair = part.split("="); + String name = ESAPI.encoder().decodeFromURL(nvpair[0]); + String value = ESAPI.encoder().decodeFromURL(nvpair[1]); + map.put(name, value); + } + catch (EncodingException e) + { + // skip the nvpair with the encoding problem - note this is already logged. + } + } + return map; + } + + /** + * {@inheritDoc} + * + * This implementation simply checks to make sure that the forward location starts with "WEB-INF" and + * is intended for use in frameworks that forward to JSP files inside the WEB-INF folder. + */ + public void sendForward(HttpServletRequest request, HttpServletResponse response, String location) throws AccessControlException,ServletException,IOException { + if (!location.startsWith("WEB-INF")) { + throw new AccessControlException("Forward failed", "Bad forward location: " + location); + } + RequestDispatcher dispatcher = request.getRequestDispatcher(location); + dispatcher.forward( request, response ); + } + + /** + * {@inheritDoc} + */ + public void sendForward( String location ) throws AccessControlException,ServletException,IOException { + sendForward( getCurrentRequest(), getCurrentResponse(), location); + } + + /** + * {@inheritDoc} + * + * This implementation checks against the list of safe redirect locations defined in ESAPI.properties. + */ + public void sendRedirect(HttpServletResponse response, String location) throws AccessControlException, IOException { + if (!ESAPI.validator().isValidRedirectLocation("Redirect", location, false)) { + logger.fatal(Logger.SECURITY_FAILURE, "Bad redirect location: " + location); + throw new AccessControlException("Redirect failed", "Bad redirect location: " + location); + } + response.sendRedirect(location); + } + + /** + * {@inheritDoc} + */ + public void sendRedirect( String location ) throws AccessControlException,IOException { + sendRedirect( getCurrentResponse(), location); + } + + /** + * {@inheritDoc} + */ + public void setContentType() { + setContentType( getCurrentResponse() ); + } + + + /** + * {@inheritDoc} + */ + public void setContentType(HttpServletResponse response) { + response.setContentType((ESAPI.securityConfiguration()).getResponseContentType()); + } + + /** + * {@inheritDoc} + */ + public void setCurrentHTTP(HttpServletRequest request, HttpServletResponse response) { + currentRequest.setRequest(request); + currentResponse.setResponse(response); + } + + /** + * {@inheritDoc} + */ + public void setHeader(HttpServletResponse response, String name, String value) { + try { + SecurityConfiguration sc = ESAPI.securityConfiguration(); + String strippedName = StringUtilities.replaceLinearWhiteSpace(name); + String strippedValue = StringUtilities.replaceLinearWhiteSpace(value); + String safeName = ESAPI.validator().getValidInput("setHeader", strippedName, "HTTPHeaderName", sc.getIntProp("HttpUtilities.MaxHeaderNameSize"), false); + String safeValue = ESAPI.validator().getValidInput("setHeader", strippedValue, "HTTPHeaderValue", sc.getIntProp("HttpUtilities.MaxHeaderValueSize"), false); + response.setHeader(safeName, safeValue); + } catch (ValidationException e) { + logger.warning(Logger.SECURITY_FAILURE, "Attempt to set invalid header denied", e); + } + } + + + /** + * {@inheritDoc} + */ + public void setHeader( String name, String value ) { + setHeader( getCurrentResponse(), name, value ); + } + + + /** + * {@inheritDoc} + */ + public void setNoCacheHeaders() { + setNoCacheHeaders( getCurrentResponse() ); + } + + /** + * {@inheritDoc} + * + * @param response + */ + public void setNoCacheHeaders(HttpServletResponse response) { + // HTTP 1.1 + response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate"); + + // HTTP 1.0 + response.setHeader("Pragma","no-cache"); + response.setDateHeader("Expires", -1); + } + + /** + * {@inheritDoc} + * + * Save the user's remember me data in an encrypted cookie and send it to the user. + * Any old remember me cookie is destroyed first. Setting this cookie will 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 will automatically be used by ESAPI to + * log the user in, if the data is valid and not expired. + * + * @param request + * @param response + */ + public String setRememberToken( HttpServletRequest request, HttpServletResponse response, String password, int maxAge, String domain, String path ) { + User user = ESAPI.authenticator().getCurrentUser(); + try { + killCookie(request, response, REMEMBER_TOKEN_COOKIE_NAME ); + // seal already contains random data + String clearToken = user.getAccountName() + "|" + password; + long expiry = ESAPI.encryptor().getRelativeTimeStamp(maxAge * 1000); + String cryptToken = ESAPI.encryptor().seal(clearToken, expiry); + SecurityConfiguration sg = ESAPI.securityConfiguration(); + boolean forceSecureCookies = sg.getBooleanProp("HttpUtilities.ForceSecureCookies"); + boolean forceHttpOnly = sg.getBooleanProp("HttpUtilities.ForceHttpOnlyCookies"); + + // Do NOT URLEncode cryptToken before creating cookie. See Google Issue # 144, + // which was marked as "WontFix". + + Cookie cookie = new Cookie( REMEMBER_TOKEN_COOKIE_NAME, cryptToken ); + cookie.setMaxAge( maxAge ); + cookie.setDomain( domain ); + cookie.setPath( path ); + cookie.setHttpOnly(forceHttpOnly); + cookie.setSecure(forceSecureCookies); + response.addCookie( cookie ); + logger.info(Logger.SECURITY_SUCCESS, "Enabled remember me token for " + user.getAccountName() ); + return cryptToken; + } catch( IntegrityException e ) { + logger.warning(Logger.SECURITY_FAILURE, "Attempt to set remember me token failed for " + user.getAccountName(), e ); + return null; + } + } + + + public String setRememberToken(HttpServletRequest request, HttpServletResponse response, int maxAge, String domain, String path){ + String rval = ""; + User user = ESAPI.authenticator().getCurrentUser(); + + try{ + killCookie(request,response, REMEMBER_TOKEN_COOKIE_NAME); + // seal already contains random data + String clearToken = user.getAccountName(); + long expiry = ESAPI.encryptor().getRelativeTimeStamp(maxAge * 1000); + String cryptToken = ESAPI.encryptor().seal(clearToken, expiry); + SecurityConfiguration sg = ESAPI.securityConfiguration(); + boolean forceSecureCookies = sg.getBooleanProp("HttpUtilities.ForceSecureCookies"); + boolean forceHttpOnly = sg.getBooleanProp("HttpUtilities.ForceHttpOnlyCookies"); + // Do NOT URLEncode cryptToken before creating cookie. See Google Issue # 144, + // which was marked as "WontFix". + + Cookie cookie = new Cookie( REMEMBER_TOKEN_COOKIE_NAME, cryptToken ); + cookie.setMaxAge( maxAge ); + cookie.setDomain( domain ); + cookie.setPath( path ); + cookie.setHttpOnly(forceHttpOnly); + cookie.setSecure(forceSecureCookies); + response.addCookie( cookie ); + logger.info(Logger.SECURITY_SUCCESS, "Enabled remember me token for " + user.getAccountName() ); + } catch( IntegrityException e){ + logger.warning(Logger.SECURITY_FAILURE, "Attempt to set remember me token failed for " + user.getAccountName(), e ); + return null; + } + + + return rval; + } + + /** + * {@inheritDoc} + */ + public String setRememberToken( String password, int maxAge, String domain, String path ) { + return setRememberToken( getCurrentRequest(), getCurrentResponse(), password, maxAge, domain, path ); + } + + + /** + * {@inheritDoc} + */ + public void verifyCSRFToken() throws IntrusionException { + verifyCSRFToken( getCurrentRequest() ); + } + + /** + * {@inheritDoc} + * + * This implementation uses the CSRF_TOKEN_NAME parameter for the token. + * + * @param request + */ + public void verifyCSRFToken(HttpServletRequest request) throws IntrusionException { + User user = ESAPI.authenticator().getCurrentUser(); + + // check if user authenticated with this request - no CSRF protection required + if( request.getAttribute(user.getCSRFToken()) != null ) { + return; + } + String token = request.getParameter(CSRF_TOKEN_NAME); + if ( !user.getCSRFToken().equals( token ) ) { + throw new IntrusionException("Authentication failed", "Possibly forged HTTP request without proper CSRF token detected"); + } + } + + /** + * {@inheritDoc} + */ + public T getSessionAttribute( String key ) { + final HttpSession session = ESAPI.currentRequest().getSession(false); + if ( session != null ) + return (T) session.getAttribute(key); + return null; + } + + /** + * {@inheritDoc} + */ + public T getSessionAttribute(HttpSession session, String key) + { + return (T) session.getAttribute(key); + } + + /** + * {@inheritDoc} + */ + public T getRequestAttribute(String key) + { + return (T) ESAPI.currentRequest().getAttribute(key); + } + + /** + * {@inheritDoc} + */ + public T getRequestAttribute(HttpServletRequest request, String key) + { + return (T) request.getAttribute( key ); + } + + ///////////////////// + + /* Helper method to encrypt using new Encryptor encryption methods and + * return the serialized ciphertext as a hex-encoded string. + */ + private String encryptString(String plaintext) throws EncryptionException { + PlainText pt = new PlainText(plaintext); + CipherText ct = ESAPI.encryptor().encrypt(pt); + byte[] serializedCiphertext = ct.asPortableSerializedByteArray(); + return Hex.encode(serializedCiphertext, false); + } + + /* Helper method to decrypt a hex-encode serialized ciphertext string and + * to decrypt it using the new Encryptor decryption methods. + */ + private String decryptString(String ciphertext) throws EncryptionException { + byte[] serializedCiphertext = Hex.decode(ciphertext); + CipherText restoredCipherText = + CipherText.fromPortableSerializedBytes(serializedCiphertext); + PlainText plaintext = ESAPI.encryptor().decrypt(restoredCipherText); + return plaintext.toString(); + } + + /* Helper method, currently used only to check if we allow anonymous + * (i.e., unauthenticated) users to perform file uploads. + * The default is do allow anonymous users. We start to see if the property + * specified by "HttpUtilities.FileUploadAllowAnonymousUser" is set to + * {@code true} (which is the default). If that is true, we immediately + * return true as no further authentication check is required. However, if + * that property is false, then we check if the user is authenticated (i.e., + * the returned {@code User} object is not null). + */ + private boolean allowUserFileUploadAccess() { + if ( fileUploadAllowAnonymousUsers ) { + return true; // Okay to allow anonymous users + } + + // Check if the current user is authenticated as per ESAPI Authenticator. + User currentUser = ESAPI.authenticator().getCurrentUser(); + + if ( ! currentUser.isAnonymous() ) { + // + // The logging here is set to 'debug' rather than 'info' + // because I figured that the web / app server access logs + // should pick up the the authenticated user and log it + // along with whatever the HTTP request is, presumably including + // the authenticated user account name. + // + // If you are using JUL for logging and want to see this debug + // output, you need to change both instances of 'INFO' in your + // 'esapi-java-logging.properties' from 'INFO' to 'FINE' (not + // 'DEBUG', which isn't a thing in JUL). + // + logger.debug(Logger.SECURITY_SUCCESS, "Allowing authenticated user '" + currentUser.getAccountName() + + " to upload file(s) via getFileUploads method."); + return true; // User is authenticated, so allow access. + } + return false; // User not authenticated; deny access. + } +} diff --git a/src/main/java/org/owasp/esapi/reference/DefaultIntrusionDetector.java b/src/main/java/org/owasp/esapi/reference/DefaultIntrusionDetector.java new file mode 100644 index 000000000..9f9c0e432 --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/DefaultIntrusionDetector.java @@ -0,0 +1,193 @@ +/** + * 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.reference; + +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Stack; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Logger; +import org.owasp.esapi.User; +import org.owasp.esapi.SecurityConfiguration.Threshold; +import org.owasp.esapi.errors.EnterpriseSecurityException; +import org.owasp.esapi.errors.IntrusionException; + +/** + * 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. This implementation stores state in the + * user's session, so that it will be properly cleaned up when the session is + * terminated. State is not otherwise persisted, so attacks that span sessions + * will not be detectable. + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @since June 1, 2007 + * @see org.owasp.esapi.IntrusionDetector + */ +public class DefaultIntrusionDetector implements org.owasp.esapi.IntrusionDetector { + + /** The logger. */ + private final Logger logger = ESAPI.getLogger("IntrusionDetector"); + + public DefaultIntrusionDetector() { + } + + /** + * {@inheritDoc} + * + * @param e + */ + public void addException(Exception e) { + if (ESAPI.securityConfiguration().getDisableIntrusionDetection()) return; + + if ( e instanceof EnterpriseSecurityException ) { + logger.warning( Logger.SECURITY_FAILURE, ((EnterpriseSecurityException)e).getLogMessage(), e ); + } else { + logger.warning( Logger.SECURITY_FAILURE, e.getMessage(), e ); + } + + // add the exception to the current user, which may trigger a detector + User user = ESAPI.authenticator().getCurrentUser(); + String eventName = e.getClass().getName(); + + if ( e instanceof IntrusionException) { + return; + } + + // add the exception to the user's store, handle IntrusionException if thrown + try { + addSecurityEvent(user, eventName); + } catch( IntrusionException ex ) { + Threshold quota = ESAPI.securityConfiguration().getQuota(eventName); + Iterator i = quota.actions.iterator(); + while ( i.hasNext() ) { + String action = (String)i.next(); + String message = "User exceeded quota of " + quota.count + " per "+ quota.interval +" seconds for event " + eventName + ". Taking actions " + quota.actions; + takeSecurityAction( action, message ); + } + } + } + + /** + * {@inheritDoc} + */ + public void addEvent(String eventName, String logMessage) throws IntrusionException { + if (ESAPI.securityConfiguration().getDisableIntrusionDetection()) return; + + logger.warning( Logger.SECURITY_FAILURE, "Security event " + eventName + " received : " + logMessage ); + + // add the event to the current user, which may trigger a detector + User user = ESAPI.authenticator().getCurrentUser(); + try { + addSecurityEvent(user, "event." + eventName); + } catch( IntrusionException ex ) { + Threshold quota = ESAPI.securityConfiguration().getQuota("event." + eventName); + Iterator i = quota.actions.iterator(); + while ( i.hasNext() ) { + String action = (String)i.next(); + String message = "User exceeded quota of " + quota.count + " per "+ quota.interval +" seconds for event " + eventName + ". Taking actions " + quota.actions; + takeSecurityAction( action, message ); + } + } + } + + /** + * Take a specified security action. In this implementation, acceptable + * actions are: log, disable, logout. + * + * @param action + * the action to take (log, disable, logout) + * @param message + * the message to log if the action is "log" + */ + private void takeSecurityAction( String action, String message ) { + if (ESAPI.securityConfiguration().getDisableIntrusionDetection()) return; + + if ( action.equals( "log" ) ) { + logger.fatal( Logger.SECURITY_FAILURE, "INTRUSION - " + message ); + } + User user = ESAPI.authenticator().getCurrentUser(); + if (user == User.ANONYMOUS) + return; + if ( action.equals( "disable" ) ) { + user.disable(); + } + if ( action.equals( "logout" ) ) { + user.logout(); + } + } + + /** + * Adds a security event to the user. These events are used to check that the user has not + * reached the security thresholds set in the properties file. + * + * @param user + * The user that caused the event. + * @param eventName + * The name of the event that occurred. + */ + private void addSecurityEvent(User user, String eventName) { + if (ESAPI.securityConfiguration().getDisableIntrusionDetection()) return; + + if ( user.isAnonymous() ) return; + + HashMap eventMap = user.getEventMap(); + + // if there is a threshold, then track this event + Threshold threshold = ESAPI.securityConfiguration().getQuota( eventName ); + if ( threshold != null ) { + Event event = (Event)eventMap.get( eventName ); + if ( event == null ) { + event = new Event( eventName ); + eventMap.put( eventName, event ); + } + // increment + event.increment(threshold.count, threshold.interval); + } + } + + private static class Event { + public String key; + public Stack times = new Stack(); + //public long count = 0; + public Event( String key ) { + this.key = key; + } + public void increment(int count, long interval) throws IntrusionException { + if (ESAPI.securityConfiguration().getDisableIntrusionDetection()) return; + + Date now = new Date(); + times.add( 0, now ); + while ( times.size() > count ) times.remove( times.size()-1 ); + if ( times.size() == count ) { + Date past = (Date)times.get( count-1 ); + long plong = past.getTime(); + long nlong = now.getTime(); + if ( nlong - plong < interval * 1000 ) { + throw new IntrusionException( "Threshold exceeded", "Exceeded threshold for " + key ); + } + } + } + } +} diff --git a/src/main/java/org/owasp/esapi/reference/DefaultRandomizer.java b/src/main/java/org/owasp/esapi/reference/DefaultRandomizer.java new file mode 100644 index 000000000..6ac3b4f70 --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/DefaultRandomizer.java @@ -0,0 +1,134 @@ +/** + * 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.reference; + +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.UUID; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.EncoderConstants; +import org.owasp.esapi.Logger; +import org.owasp.esapi.Randomizer; +import org.owasp.esapi.errors.EncryptionException; + +/** + * 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. + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @since June 1, 2007 + * @see org.owasp.esapi.Randomizer + */ +public class DefaultRandomizer implements org.owasp.esapi.Randomizer { + private static volatile Randomizer singletonInstance; + + public static Randomizer getInstance() { + if ( singletonInstance == null ) { + synchronized ( DefaultRandomizer.class ) { + if ( singletonInstance == null ) { + singletonInstance = new DefaultRandomizer(); + } + } + } + return singletonInstance; + } + + /** The sr. */ + private SecureRandom secureRandom = null; + + /** The logger. */ + private final Logger logger = ESAPI.getLogger("Randomizer"); + + private DefaultRandomizer() { + String algorithm = ESAPI.securityConfiguration().getRandomAlgorithm(); + try { + secureRandom = SecureRandom.getInstance(algorithm); + } catch (NoSuchAlgorithmException e) { + // Can't throw an exception from the constructor, but this will get + // it logged and tracked + new EncryptionException("Error creating randomizer", "Can't find random algorithm " + algorithm, e); + } + } + + /** + * {@inheritDoc} + */ + public String getRandomString(int length, char[] characterSet) { + StringBuilder sb = new StringBuilder(); + for (int loop = 0; loop < length; loop++) { + int index = secureRandom.nextInt(characterSet.length); + sb.append(characterSet[index]); + } + String nonce = sb.toString(); + return nonce; + } + + /** + * {@inheritDoc} + */ + public boolean getRandomBoolean() { + return secureRandom.nextBoolean(); + } + + /** + * {@inheritDoc} + */ + public int getRandomInteger(int min, int max) { + return secureRandom.nextInt(max - min) + min; + } + + /** + * {@inheritDoc} + */ + public long getRandomLong() { + return secureRandom.nextLong(); + } + + /** + * {@inheritDoc} + */ + public float getRandomReal(float min, float max) { + float factor = max - min; + return secureRandom.nextFloat() * factor + min; + } + + /** + * {@inheritDoc} + */ + public String getRandomFilename(String extension) { + String fn = getRandomString(12, EncoderConstants.CHAR_ALPHANUMERICS) + "." + extension; + logger.debug(Logger.SECURITY_SUCCESS, "Generated new random filename: " + fn ); + return fn; + } + + /** + * {@inheritDoc} + */ + public String getRandomGUID() throws EncryptionException { + return UUID.randomUUID().toString(); + } + + /** + * {@inheritDoc} + */ + public byte[] getRandomBytes(int n) { + byte[] result = new byte[ n ]; + secureRandom.nextBytes(result); + return result; + } + +} diff --git a/src/main/java/org/owasp/esapi/reference/DefaultSecurityConfiguration.java b/src/main/java/org/owasp/esapi/reference/DefaultSecurityConfiguration.java new file mode 100644 index 000000000..7b622c32d --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/DefaultSecurityConfiguration.java @@ -0,0 +1,1517 @@ +/** + * 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.reference; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +import org.apache.commons.lang.text.StrTokenizer; +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Logger; +import org.owasp.esapi.PropNames; // <== Actual property names moved to here. Eventually we'll do static import. +import org.owasp.esapi.PropNames.DefaultSearchPath; +import org.owasp.esapi.SecurityConfiguration; +import org.owasp.esapi.configuration.EsapiPropertyManager; +import org.owasp.esapi.errors.ConfigurationException; + +/** + * Thse reference implementation class for {@code SecurityConfiguration} manages all the settings used by the ESAPI + * in a single place. In this reference implementation, resources can be put in several locations, which are + * searched in the following order: + *

+ *

    + *
  1. + * Inside a directory set with a call to SecurityConfiguration.setResourceDirectory( "C:\temp\resources" ). + *

    + * CAUTION: Generally this technique should be avoided if you are + * using ESAPI in a resusable library, as it makes it very difficult for an + * application using your library to use its own version of + * ESAPI.properties. + *

    + * The only exception might be if you are writing a wrapper library for ESAPI + * and wish to provide a set of ESAPI properties that the application cannot accidentally + * change. However, selecting this option won't intentionally prevent changing ESAPI.properties + * unless you are signing the jar * and somehow forcing the verifiction of its digital signature at + * runtime. That's because it's easy enough to unjar your library, edit the ESAPI.properties + * file and then re-jar the library. + *

    + * This option was probably more intended for use by web applications by embedding + * them as resources in .war or .ear files, possibly with the intent of + * dissauding operations staff from making "improvements", a practice which + * makes much less--if any--sense in the era of DevOps and DevSecOps. + *

    + *
  2. + *
  3. + * Inside the {@code System.getProperty( "org.owasp.esapi.resources" )} directory. + * You can set this on the java command line as follows (for example): + *
    + *
    + *         java -Dorg.owasp.esapi.resources="C:\apps\myApp\resources"
    + * 
    + * You may have to add this to the start-up script that starts your web server. For example, for Tomcat, + * in the "catalina" script that starts Tomcat, you can set the JAVA_OPTS variable to the {@code -D} string above. + *
  4. + *
  5. + * Inside the {@code System.getProperty( "user.home" ) + "/.esapi"} directory (supported for backward compatibility) or + * inside the {@code System.getProperty( "user.home" ) + "/esapi"} directory. + *
  6. + *
  7. + * The first ".esapi" or "esapi" directory on the classpath. (The former for backward compatibility.) + *
  8. + *
+ *

+ * Once the ESAPI 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. (But see the above cautionary + * note if you are using ESAPI in a reusable library.) + *

+ * WARNING: Do not forget to update ESAPI.properties to change the master key and other security critical settings + * as well as reviewing changes in the esapi-<vers-configuration.jar for differences + * with your current version to see if any important properties were added or removed. + *

+ * DEPRECATION WARNING: All of the variables of the type '{@code public static final String}' + * are now declared and defined in the {@code org.owasp.esapi.PropNames}. These public fields + * representing property names and values in this class will be eventually deleted and + * no longer available, so please migrate to the corresponding names in {@code PropNames}. Removal of these + * public fields from this class will likely occur sometime in 2Q2024. + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @author Jim Manico (jim .at. manico.net) Manico.net + * @author Kevin W. Wall (kevin.w.wall .at. gmail.com) + * + */ + +public class DefaultSecurityConfiguration implements SecurityConfiguration { + private static volatile SecurityConfiguration instance = null; + + public static SecurityConfiguration getInstance() { + if ( instance == null ) { + synchronized (DefaultSecurityConfiguration.class) { + if ( instance == null ) { + instance = new DefaultSecurityConfiguration(); + } + } + } + return instance; + } + + private Properties properties = null; + private String cipherXformFromESAPIProp = null; // New in ESAPI 2.0 + private String cipherXformCurrent = null; // New in ESAPI 2.0 + + /** The name of the ESAPI property file. + * @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. + */ + @Deprecated public static final String DEFAULT_RESOURCE_FILE = PropNames.DEFAULT_RESOURCE_FILE; + + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String REMEMBER_TOKEN_DURATION = PropNames.REMEMBER_TOKEN_DURATION; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String IDLE_TIMEOUT_DURATION = PropNames.IDLE_TIMEOUT_DURATION; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String ABSOLUTE_TIMEOUT_DURATION = PropNames.ABSOLUTE_TIMEOUT_DURATION; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String ALLOWED_LOGIN_ATTEMPTS = PropNames.ALLOWED_LOGIN_ATTEMPTS; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String USERNAME_PARAMETER_NAME = PropNames.USERNAME_PARAMETER_NAME; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String PASSWORD_PARAMETER_NAME = PropNames.PASSWORD_PARAMETER_NAME; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String MAX_OLD_PASSWORD_HASHES = PropNames.MAX_OLD_PASSWORD_HASHES; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String ALLOW_MULTIPLE_ENCODING = PropNames.ALLOW_MULTIPLE_ENCODING; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String ALLOW_MIXED_ENCODING = PropNames.ALLOW_MIXED_ENCODING ; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String CANONICALIZATION_CODECS = PropNames.CANONICALIZATION_CODECS; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String DISABLE_INTRUSION_DETECTION = PropNames.DISABLE_INTRUSION_DETECTION ; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String MASTER_KEY = PropNames.MASTER_KEY; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String MASTER_SALT = PropNames.MASTER_SALT; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String KEY_LENGTH = PropNames.KEY_LENGTH; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String ENCRYPTION_ALGORITHM = PropNames.ENCRYPTION_ALGORITHM; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String HASH_ALGORITHM = PropNames.HASH_ALGORITHM; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String HASH_ITERATIONS = PropNames.HASH_ITERATIONS; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String CHARACTER_ENCODING = PropNames.CHARACTER_ENCODING; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String RANDOM_ALGORITHM = PropNames.RANDOM_ALGORITHM; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String DIGITAL_SIGNATURE_ALGORITHM = PropNames.DIGITAL_SIGNATURE_ALGORITHM; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String DIGITAL_SIGNATURE_KEY_LENGTH = PropNames.DIGITAL_SIGNATURE_KEY_LENGTH; + + // ==================================// + // New in ESAPI Java 2.x // + // ================================= // + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String PREFERRED_JCE_PROVIDER = PropNames.PREFERRED_JCE_PROVIDER; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String CIPHER_TRANSFORMATION_IMPLEMENTATION = PropNames.CIPHER_TRANSFORMATION_IMPLEMENTATION; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String CIPHERTEXT_USE_MAC = PropNames.CIPHERTEXT_USE_MAC; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String PLAINTEXT_OVERWRITE = PropNames.PLAINTEXT_OVERWRITE; + + @Deprecated public static final String IV_TYPE = PropNames.IV_TYPE; // Will be removed in future release. + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String COMBINED_CIPHER_MODES = PropNames.COMBINED_CIPHER_MODES; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String ADDITIONAL_ALLOWED_CIPHER_MODES = PropNames.ADDITIONAL_ALLOWED_CIPHER_MODES; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String KDF_PRF_ALG = PropNames.KDF_PRF_ALG; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String PRINT_PROPERTIES_WHEN_LOADED = PropNames.PRINT_PROPERTIES_WHEN_LOADED; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String WORKING_DIRECTORY = PropNames.WORKING_DIRECTORY; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String APPROVED_EXECUTABLES = PropNames.APPROVED_EXECUTABLES; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String FORCE_HTTPONLYSESSION = PropNames.FORCE_HTTPONLYSESSION; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String FORCE_SECURESESSION = PropNames.FORCE_SECURESESSION; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String FORCE_HTTPONLYCOOKIES = PropNames.FORCE_HTTPONLYCOOKIES; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String FORCE_SECURECOOKIES = PropNames.FORCE_SECURECOOKIES; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String MAX_HTTP_HEADER_SIZE = PropNames.MAX_HTTP_HEADER_SIZE; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String UPLOAD_DIRECTORY = PropNames.UPLOAD_DIRECTORY; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String UPLOAD_TEMP_DIRECTORY = PropNames.UPLOAD_TEMP_DIRECTORY; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String APPROVED_UPLOAD_EXTENSIONS = PropNames.APPROVED_UPLOAD_EXTENSIONS; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String MAX_UPLOAD_FILE_BYTES = PropNames.MAX_UPLOAD_FILE_BYTES; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String RESPONSE_CONTENT_TYPE = PropNames.RESPONSE_CONTENT_TYPE; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String HTTP_SESSION_ID_NAME = PropNames.HTTP_SESSION_ID_NAME; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String APPLICATION_NAME = PropNames.APPLICATION_NAME; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String LOG_ENCODING_REQUIRED = PropNames.LOG_ENCODING_REQUIRED; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String LOG_APPLICATION_NAME = PropNames.LOG_APPLICATION_NAME; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String LOG_SERVER_IP = PropNames.LOG_SERVER_IP; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String LOG_USER_INFO = PropNames.LOG_USER_INFO; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String LOG_CLIENT_INFO = PropNames.LOG_CLIENT_INFO; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String VALIDATION_PROPERTIES = PropNames.VALIDATION_PROPERTIES; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String VALIDATION_PROPERTIES_MULTIVALUED = PropNames.VALIDATION_PROPERTIES_MULTIVALUED; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String ACCEPT_LENIENT_DATES = PropNames.ACCEPT_LENIENT_DATES; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String VALIDATOR_HTML_VALIDATION_ACTION = PropNames.VALIDATOR_HTML_VALIDATION_ACTION; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String VALIDATOR_HTML_VALIDATION_CONFIGURATION_FILE = PropNames.VALIDATOR_HTML_VALIDATION_CONFIGURATION_FILE; + + /** + * 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) + * @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. + */ + @Deprecated public static final String DISCARD_LOGSPECIAL = PropNames.DISCARD_LOGSPECIAL; + + // We assume that this does not change in the middle of processing the + // ESAPI.properties files and thus only fetch its value once. + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated private static final String logSpecialValue = System.getProperty( PropNames.DISCARD_LOGSPECIAL, "false" ); + + + protected final int MAX_REDIRECT_LOCATION = 1000; + + + /* + * Implementation Keys + */ + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String LOG_IMPLEMENTATION = PropNames.LOG_IMPLEMENTATION; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String AUTHENTICATION_IMPLEMENTATION = PropNames.AUTHENTICATION_IMPLEMENTATION; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String ENCODER_IMPLEMENTATION = PropNames.ENCODER_IMPLEMENTATION; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String ACCESS_CONTROL_IMPLEMENTATION = PropNames.ACCESS_CONTROL_IMPLEMENTATION; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String ENCRYPTION_IMPLEMENTATION = PropNames.ENCRYPTION_IMPLEMENTATION; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String INTRUSION_DETECTION_IMPLEMENTATION = PropNames.INTRUSION_DETECTION_IMPLEMENTATION; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String RANDOMIZER_IMPLEMENTATION = PropNames.RANDOMIZER_IMPLEMENTATION; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String EXECUTOR_IMPLEMENTATION = PropNames.EXECUTOR_IMPLEMENTATION; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String VALIDATOR_IMPLEMENTATION = PropNames.VALIDATOR_IMPLEMENTATION; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String HTTP_UTILITIES_IMPLEMENTATION = PropNames.HTTP_UTILITIES_IMPLEMENTATION; + + + /* + * Default Implementations + */ + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String DEFAULT_LOG_IMPLEMENTATION = PropNames.DEFAULT_LOG_IMPLEMENTATION; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String DEFAULT_AUTHENTICATION_IMPLEMENTATION = PropNames.DEFAULT_AUTHENTICATION_IMPLEMENTATION; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String DEFAULT_ENCODER_IMPLEMENTATION = PropNames.DEFAULT_ENCODER_IMPLEMENTATION; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String DEFAULT_ACCESS_CONTROL_IMPLEMENTATION = PropNames.DEFAULT_ACCESS_CONTROL_IMPLEMENTATION; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String DEFAULT_ENCRYPTION_IMPLEMENTATION = PropNames.DEFAULT_ENCRYPTION_IMPLEMENTATION; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String DEFAULT_INTRUSION_DETECTION_IMPLEMENTATION = PropNames.DEFAULT_INTRUSION_DETECTION_IMPLEMENTATION; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String DEFAULT_RANDOMIZER_IMPLEMENTATION = PropNames.DEFAULT_RANDOMIZER_IMPLEMENTATION; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String DEFAULT_EXECUTOR_IMPLEMENTATION = PropNames.DEFAULT_EXECUTOR_IMPLEMENTATION; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String DEFAULT_HTTP_UTILITIES_IMPLEMENTATION = PropNames.DEFAULT_HTTP_UTILITIES_IMPLEMENTATION; + + /** @deprecated Use same field name, but from {@code org.owasp.esapi.PropNames} instead. */ + @Deprecated public static final String DEFAULT_VALIDATOR_IMPLEMENTATION = PropNames.DEFAULT_VALIDATOR_IMPLEMENTATION; + + private static final Map patternCache = new HashMap(); + + /* + * Absolute path to the user.home. No longer includes the ESAPI portion as it used to. + */ + private static final String userHome = System.getProperty("user.home" ); + /* + * Absolute path to the customDirectory + */ // DISCUSS: Implicit assumption here that there is no SecurityManager installed enforcing the + // prevention of reading system properties. Otherwise this will fail with SecurityException. + private static String customDirectory = System.getProperty("org.owasp.esapi.resources"); + /* + * Relative path to the resourceDirectory. Relative to the classpath. + * Specifically, ClassLoader.getResource(resourceDirectory + filename) will + * be used to load the file. + */ + private String resourceDirectory = ".esapi"; // For backward compatibility (vs. "esapi") + private final String resourceFile; + private EsapiPropertyManager esapiPropertyManager; + + + /** + * Instantiates a new configuration, using the provided property file name. + * + * @param resourceFile The name of the property file to load + */ + DefaultSecurityConfiguration(String resourceFile) { + this.resourceFile = resourceFile; + // load security configuration + try { + this.esapiPropertyManager = new EsapiPropertyManager(); + loadConfiguration(); + this.setCipherXProperties(); + } catch( IOException e ) { + logSpecial("Failed to load security configuration", e ); + throw new ConfigurationException("Failed to load security configuration", e); + } + } + + /** + * Instantiates a new configuration with the supplied properties. + * + * Warning - if the setResourceDirectory() method is invoked the properties will + * be re-loaded, replacing the supplied properties. + * + * @param properties + */ + public DefaultSecurityConfiguration(Properties properties) { + resourceFile = DEFAULT_RESOURCE_FILE; + try { + this.esapiPropertyManager = new EsapiPropertyManager(); + // Do NOT call loadConfiguration() here! + } catch( IOException e ) { + logSpecial("Failed to load security configuration", e ); + throw new ConfigurationException("Failed to load security configuration", e); + } + this.properties = properties; + this.setCipherXProperties(); + } + + /** + * Instantiates a new configuration. + */ + public DefaultSecurityConfiguration(){ + this(DEFAULT_RESOURCE_FILE); + } + private void setCipherXProperties() { + // TODO: FUTURE: Replace by future CryptoControls class??? + // See SecurityConfiguration.setCipherTransformation() for + // explanation of this. + // (Propose this in a future 2.x release via future email to ESAPI-DEV list.) + cipherXformFromESAPIProp = + getESAPIProperty(CIPHER_TRANSFORMATION_IMPLEMENTATION, + "AES/CBC/PKCS5Padding"); + cipherXformCurrent = cipherXformFromESAPIProp; + } + + /** + * {@inheritDoc} + */ + public String getApplicationName() { + return getESAPIProperty(APPLICATION_NAME, "DefaultName"); + } + + /** + * {@inheritDoc} + */ + public String getLogImplementation() { + return getESAPIProperty(LOG_IMPLEMENTATION, DEFAULT_LOG_IMPLEMENTATION); + } + + /** + * {@inheritDoc} + */ + public String getAuthenticationImplementation() { + return getESAPIProperty(AUTHENTICATION_IMPLEMENTATION, DEFAULT_AUTHENTICATION_IMPLEMENTATION); + } + + /** + * {@inheritDoc} + */ + public String getEncoderImplementation() { + return getESAPIProperty(ENCODER_IMPLEMENTATION, DEFAULT_ENCODER_IMPLEMENTATION); + } + + /** + * {@inheritDoc} + */ + public String getAccessControlImplementation() { + return getESAPIProperty(ACCESS_CONTROL_IMPLEMENTATION, DEFAULT_ACCESS_CONTROL_IMPLEMENTATION); + } + + /** + * {@inheritDoc} + */ + public String getEncryptionImplementation() { + return getESAPIProperty(ENCRYPTION_IMPLEMENTATION, DEFAULT_ENCRYPTION_IMPLEMENTATION); + } + + /** + * {@inheritDoc} + */ + public String getIntrusionDetectionImplementation() { + return getESAPIProperty(INTRUSION_DETECTION_IMPLEMENTATION, DEFAULT_INTRUSION_DETECTION_IMPLEMENTATION); + } + + /** + * {@inheritDoc} + */ + public String getRandomizerImplementation() { + return getESAPIProperty(RANDOMIZER_IMPLEMENTATION, DEFAULT_RANDOMIZER_IMPLEMENTATION); + } + + /** + * {@inheritDoc} + */ + public String getExecutorImplementation() { + return getESAPIProperty(EXECUTOR_IMPLEMENTATION, DEFAULT_EXECUTOR_IMPLEMENTATION); + } + + /** + * {@inheritDoc} + */ + public String getHTTPUtilitiesImplementation() { + return getESAPIProperty(HTTP_UTILITIES_IMPLEMENTATION, DEFAULT_HTTP_UTILITIES_IMPLEMENTATION); + } + + /** + * {@inheritDoc} + */ + public String getValidationImplementation() { + return getESAPIProperty(VALIDATOR_IMPLEMENTATION, DEFAULT_VALIDATOR_IMPLEMENTATION); + } + + + /** + * {@inheritDoc} + */ + public byte[] getMasterKey() { + byte[] key = getESAPIPropertyEncoded( MASTER_KEY, null ); + if ( key == null || key.length == 0 ) { + throw new ConfigurationException("Property '" + MASTER_KEY + + "' missing or empty in ESAPI.properties file."); + } + return key; + } + + /** + * {@inheritDoc} + */ + public void setResourceDirectory( String dir ) { + resourceDirectory = dir; + logSpecial( "Reset resource directory to: " + dir, null ); + + // reload configuration if necessary + try { + this.loadConfiguration(); + } catch( IOException e ) { + logSpecial("Failed to load security configuration from " + dir, e); + } + } + + public int getEncryptionKeyLength() { + return getESAPIProperty(KEY_LENGTH, 128 ); + } + + /** + * {@inheritDoc} + */ + public byte[] getMasterSalt() { + byte[] salt = getESAPIPropertyEncoded( MASTER_SALT, null ); + if ( salt == null || salt.length == 0 ) { + throw new ConfigurationException("Property '" + MASTER_SALT + + "' missing or empty in ESAPI.properties file."); + } + return salt; + } + + /** + * {@inheritDoc} + */ + public List getAllowedExecutables() { + String def = ""; + String[] exList = getESAPIProperty(APPROVED_EXECUTABLES,def).split(","); + return Arrays.asList(exList); + } + + /** + * {@inheritDoc} + */ + public List getAllowedFileExtensions() { + String def = ".pdf,.txt,.jpg,.png"; + String[] extList = getESAPIProperty(APPROVED_UPLOAD_EXTENSIONS,def).split(","); + return Arrays.asList(extList); + } + + /** + * {@inheritDoc} + */ + public int getAllowedFileUploadSize() { + return getESAPIProperty(MAX_UPLOAD_FILE_BYTES, 5000000); + } + + + private Properties loadPropertiesFromStream( InputStream is, String name ) throws IOException { + Properties config = new Properties(); + try { + config.load(is); + logSpecial("Loaded '" + name + "' properties file", null); + } finally { + if ( is != null ) try { is.close(); } catch( Exception e ) {} + } + return config; + } + + /** + * Load configuration. Never prints properties. + * + * @throws java.io.IOException + * if the file is inaccessible + */ + protected void loadConfiguration() throws IOException { + try { + //first attempt file IO loading of properties + logSpecial("Attempting to load " + resourceFile + " via file I/O."); + properties = loadPropertiesFromStream(getResourceStream(resourceFile), resourceFile); + } catch (Exception iae) { + //if file I/O loading fails, attempt classpath based loading next + logSpecial("Loading " + resourceFile + " via file I/O failed. Exception was: " + iae); + logSpecial("Attempting to load " + resourceFile + " via the classpath."); + try { + properties = loadConfigurationFromClasspath(resourceFile); + } catch (Exception e) { + logSpecial(resourceFile + " could not be loaded by any means. Fail.", e); + throw new ConfigurationException(resourceFile + " could not be loaded by any means. Fail.", e); + } + } + + // if properties loaded properly above, get validation properties and merge them into the main properties + if (properties != null) { + final Iterator validationPropFileNames; + + //defaults to single-valued for backwards compatibility + final boolean multivalued= getESAPIProperty(VALIDATION_PROPERTIES_MULTIVALUED, false); + final String validationPropValue = getESAPIProperty(VALIDATION_PROPERTIES, "validation.properties"); + + if(multivalued){ + // the following cast warning goes away if the apache commons lib is updated to current version + validationPropFileNames = StrTokenizer.getCSVInstance(validationPropValue); + } else { + validationPropFileNames = Collections.singletonList(validationPropValue).iterator(); + } + + //clear any cached validation patterns so they can be reloaded from validation.properties + patternCache.clear(); + while(validationPropFileNames.hasNext()){ + String validationPropFileName = validationPropFileNames.next(); + Properties validationProperties = null; + try { + //first attempt file IO loading of properties + logSpecial("Attempting to load " + validationPropFileName + " via file I/O."); + validationProperties = loadPropertiesFromStream(getResourceStream(validationPropFileName), validationPropFileName); + } catch (Exception iae) { + //if file I/O loading fails, attempt classpath based loading next + logSpecial("Loading " + validationPropFileName + " via file I/O failed."); + logSpecial("Attempting to load " + validationPropFileName + " via the classpath."); + try { + validationProperties = loadConfigurationFromClasspath(validationPropFileName); + } catch (Exception e) { + logSpecial(validationPropFileName + " could not be loaded by any means. fail.", e); + } + } + + if (validationProperties != null) { + Iterator i = validationProperties.keySet().iterator(); + while( i.hasNext() ) { + String key = (String)i.next(); + String value = validationProperties.getProperty(key); + properties.put( key, value); + } + } + + if ( shouldPrintProperties() ) { + // Gotta give them something. + logSpecial("DefaultSecurityConfiguration: The code to print all the properties is currently commented out"); + + //FIXME - make this chunk configurable + /* + logSpecial(" ========Master Configuration========", null); + //logSpecial( " ResourceDirectory: " + DefaultSecurityConfiguration.resourceDirectory ); + Iterator j = new TreeSet( properties.keySet() ).iterator(); + while (j.hasNext()) { + String key = (String)j.next(); + // print out properties, but not sensitive ones like MasterKey and MasterSalt + if ( !key.contains( "Master" ) ) { + logSpecial(" | " + key + "=" + properties.get(key), null); + } + } + */ + } + } + } + } + + /** + * @param filename + * @return An {@code InputStream} associated with the specified file name as + * a resource stream. + * @throws IOException + * If the file cannot be found or opened for reading. + */ + public InputStream getResourceStream(String filename) throws IOException { + if (filename == null) { + return null; + } + + try { + File f = getResourceFile(filename); + if (f != null && f.exists()) { + return new FileInputStream(f); + } + } catch (Exception e) { + } + + throw new FileNotFoundException(); + } + + /** + * {@inheritDoc} + */ + public File getResourceFile(String filename) { + logSpecial("Attempting to load " + filename + " as resource file via file I/O."); + + if (filename == null) { + logSpecial("Failed to load properties via FileIO. Filename is null."); + return null; // not found. + } + + File f = null; + + // first, allow command line overrides. -Dorg.owasp.esapi.resources + // directory + f = new File(customDirectory, filename); + if (customDirectory != null && f.canRead()) { + logSpecial("Found in 'org.owasp.esapi.resources' directory: " + f.getAbsolutePath()); + return f; + } else { + logSpecial("Not found in 'org.owasp.esapi.resources' directory or file not readable: " + f.getAbsolutePath()); + } + + // if not found, then try the programmatically set resource directory + // (this defaults to SystemResource directory/resourceFile + URL fileUrl = ClassLoader.getSystemResource(resourceDirectory + "/" + filename); + if ( fileUrl == null ) { + fileUrl = ClassLoader.getSystemResource("esapi/" + filename); + } + + if (fileUrl != null) { + try { + String fileLocation = fileUrl.toURI().getPath(); + f = new File(fileLocation); + if (f.exists()) { + logSpecial("Found in SystemResource Directory/resourceDirectory: " + f.getAbsolutePath()); + return f; + } else { + logSpecial("Not found in SystemResource Directory/resourceDirectory (this should never happen): " + f.getAbsolutePath()); + } + } catch (URISyntaxException e) { + logSpecial("Error while converting URL " + fileUrl + " to file path: " + e.getMessage()); + } + } else { + logSpecial("Not found in SystemResource Directory/resourceDirectory: " + resourceDirectory + File.separator + filename); + } + + // If not found, then try immediately under user's home directory first in + // userHome + "/.esapi" and secondly under + // userHome + "/esapi" + // We look in that order because of backward compatibility issues. + String homeDir = userHome; + if ( homeDir == null ) { + homeDir = ""; // Without this, homeDir + "/.esapi" would produce + // the string "null/.esapi" which surely is not intended. + } + // First look under ".esapi" (for reasons of backward compatibility). + f = new File(homeDir + "/.esapi", filename); + if ( f.canRead() ) { + logSpecial("[Compatibility] Found in 'user.home' directory: " + f.getAbsolutePath()); + return f; + } else { + // Didn't find it under old directory ".esapi" so now look under the "esapi" directory. + f = new File(homeDir + "/esapi", filename); + if ( f.canRead() ) { + logSpecial("Found in 'user.home' directory: " + f.getAbsolutePath()); + return f; + } else { + logSpecial("Not found in 'user.home' (" + homeDir + ") directory: " + f.getAbsolutePath()); + } + } + + // return null if not found + return null; + } + + /** + * Used to load ESAPI.properties from a variety of different classpath locations. The order is described in the + * class overview Javadoc for this class. + * + * @param fileName The properties file filename. + */ + private Properties loadConfigurationFromClasspath(String fileName) throws IllegalArgumentException { + Properties result = null; + InputStream in = null; + + ClassLoader[] loaders = new ClassLoader[] { + Thread.currentThread().getContextClassLoader(), + ClassLoader.getSystemClassLoader(), + getClass().getClassLoader() + }; + String[] classLoaderNames = { + "current thread context class loader", + "system class loader", + "class loader for DefaultSecurityConfiguration class" + }; + + ClassLoader currentLoader = null; + for (int i = 0; i < loaders.length; i++) { + if (loaders[i] != null) { + currentLoader = loaders[i]; + try { + // try root + String currentClasspathSearchLocation = "/ (root)"; + // Note: do NOT add '/' anywhere here even though root value is empty string! + // Note that since DefaultSearchPath.ROOT.value() is now "" (the empty string), + // then this is logically equivalent to what we used to have, which was: + // + // in = loaders[i].getResourceAsStream(fileName); + // + in = loaders[i].getResourceAsStream(DefaultSearchPath.ROOT.value() + fileName); + + // try resourceDirectory folder + if (in == null) { + currentClasspathSearchLocation = resourceDirectory + "/"; + in = currentLoader.getResourceAsStream(DefaultSearchPath.RESOURCE_DIRECTORY.value() + fileName); + } + + // try .esapi folder. Look here first for backward compatibility. + if (in == null) { + currentClasspathSearchLocation = ".esapi/"; + in = currentLoader.getResourceAsStream(DefaultSearchPath.DOT_ESAPI.value() + fileName); + } + + // try esapi folder (new directory) + if (in == null) { + currentClasspathSearchLocation = "esapi/"; + in = currentLoader.getResourceAsStream(DefaultSearchPath.ESAPI.value() + fileName); + } + + // try resources folder + if (in == null) { + currentClasspathSearchLocation = "resources/"; + in = currentLoader.getResourceAsStream(DefaultSearchPath.RESOURCES.value() + fileName); + } + + // try src/main/resources folder + if (in == null) { + currentClasspathSearchLocation = "src/main/resources/"; + in = currentLoader.getResourceAsStream(DefaultSearchPath.SRC_MAIN_RESOURCES.value() + fileName); + } + + // now load the properties + if (in != null) { + result = new Properties(); + result.load(in); // Can throw IOException + logSpecial("SUCCESSFULLY LOADED " + fileName + " via the CLASSPATH from '" + + currentClasspathSearchLocation + "' using " + classLoaderNames[i] + "!"); + break; // Outta here since we've found and loaded it. + } + } catch (Exception e) { + result = null; + } finally { + try { + in.close(); + } catch (Exception e) { + } + } + } + } + + if (result == null) { + // CHECKME: This is odd...why not ConfigurationException? + throw new IllegalArgumentException("Failed to load " + resourceFile + " as a classloader resource."); + } + + return result; + } + + /** + * Log to standard output (i.e., {@code System.out}. This method is + * synchronized to reduce the possibility of interleaving the message + * output (since the {@code System.out} {@code PrintStream} is buffered) + * it invoked from multiple threads. Output is discarded if the + * {@code System} property "org.owasp.esapi.logSpecial.discard" is set to + * {@code true}. + * + * @param msg Message to be logged. + * @param t Associated exception that was caught. The class name and + * exception message is also logged. + */ + public final synchronized static void logToStdout(String msg, Throwable t) { + // Note that this class was made final because it is called from this class' + // CTOR and we want to prohibit someone from easily doing sneaky + // things like subclassing this class and inserting a malicious code as a + // shim. Of course, really in hindsight, this entire class should have been + // declared 'final', but doing so at this point would likely break someone's + // code, including possibly some of our own test code. But since this is a + // new method, we can get away with it here. + boolean discard = logSpecialValue.trim().equalsIgnoreCase("true"); + if ( discard ) { + return; // Output is discarded! + } + if ( t == null ) { + System.out.println("ESAPI: " + msg); + } else { + System.out.println("ESAPI: " + msg + + ". Caught " + t.getClass().getName() + + "; exception message was: " + t); + } + } + + /** + * Used to log errors to the console during the loading of the properties file itself. Can't use + * standard logging in this case, since the Logger may not be initialized yet. Output is sent to + * {@code PrintStream} {@code System.out}. Output is discarded if the {@code System} property + * "org.owasp.esapi.logSpecial.discard" is set to {@code true}. + * + * @param message The message to send to the console. + * @param e The error that occurred. (This value printed via {@code e.toString()}.) + */ + private void logSpecial(String message, Throwable e) { + logToStdout(message, e); + } + + /** + * Used to log errors to the console during the loading of the properties file itself. Can't use + * standard logging in this case, since the Logger may not be initialized yet. Output is sent to + * {@code PrintStream} {@code System.out}. Output is discarded if the {@code System} property + * "org.owasp.esapi.logSpecial.discard" is set to {@code true}. + * + * @param message The message to send to the console. + */ + private void logSpecial(String message) { + logToStdout(message, null); + } + /** + * {@inheritDoc} + */ + public String getPasswordParameterName() { + return getESAPIProperty(PASSWORD_PARAMETER_NAME, "password"); + } + + /** + * {@inheritDoc} + */ + public String getUsernameParameterName() { + return getESAPIProperty(USERNAME_PARAMETER_NAME, "username"); + } + + /** + * {@inheritDoc} + */ + public String getEncryptionAlgorithm() { + return getESAPIProperty(ENCRYPTION_ALGORITHM, "AES"); + } + + /** + * {@inheritDoc} + */ + public String getCipherTransformation() { + // Assertion should be okay here. An NPE is likely at runtime if disabled. + assert cipherXformCurrent != null : "Current cipher transformation is null"; + return cipherXformCurrent; + } + + /** + * {@inheritDoc} + */ + public String setCipherTransformation(String cipherXform) { + String previous = getCipherTransformation(); + if ( cipherXform == null ) { + // Special case... means set it to original value from ESAPI.properties + cipherXformCurrent = cipherXformFromESAPIProp; + } else { + if ( cipherXform.trim().equals("") ) { + throw new ConfigurationException("Cipher transformation cannot be just white space or empty string"); + } + cipherXformCurrent = cipherXform; // Note: No other sanity checks!!! + } + return previous; + } + + /** + * {@inheritDoc} + */ + public boolean useMACforCipherText() { + return getESAPIProperty(CIPHERTEXT_USE_MAC, true); + } + + /** + * {@inheritDoc} + */ + public boolean overwritePlainText() { + return getESAPIProperty(PLAINTEXT_OVERWRITE, true); + } + + /** + * {@inheritDoc} + */ + @Deprecated + public String getIVType() { + String value = getESAPIProperty(IV_TYPE, "random"); + if ( value.equalsIgnoreCase("random") ) { + return value; + } else if ( value.equalsIgnoreCase("fixed") ) { + logSpecial("WARNING: Property '" + IV_TYPE + "=fixed' is no longer supported AT ALL!!! It had been deprecated since 2.2.0.0 and back then, was announced it would be removed in release 2.3.0.0. It was originally intended to support legacy applications, but is inherently insecure, especially with any streaming mode."); + throw new ConfigurationException("'" + IV_TYPE + "=fixed' is no longer supported AT ALL. It has been deprecated since release 2.2 and has been removed since 2.3."); + } else if ( value.equalsIgnoreCase("specified") ) { + // Originally, this was planned for future implementation where setting + // Encryptor.ChooseIVMethod=specified + // would have allowed a dev to write their own static method to be + // invoked in a future TBD property, but that is a recipe for + // disaster. So, it's not going to happen. Ever. + throw new ConfigurationException("Contrary to previous internal comments, '" + IV_TYPE + "=specified' is not going to be supported -- ever."); + } else { + logSpecial("WARNING: '" + value + "' is illegal value for " + IV_TYPE + + ". Using 'random' for the IV type."); + } + return "random"; + } + + /** + * {@inheritDoc} + */ + public String getHashAlgorithm() { + return getESAPIProperty(HASH_ALGORITHM, "SHA-512"); + } + + /** + * {@inheritDoc} + */ + public int getHashIterations() { + return getESAPIProperty(HASH_ITERATIONS, 1024); + } + + /** + * {@inheritDoc} + */ + public String getKDFPseudoRandomFunction() { + return getESAPIProperty(KDF_PRF_ALG, "HmacSHA256"); // NSA recommended SHA2 or better. + } + + /** + * {@inheritDoc} + */ + public String getCharacterEncoding() { + return getESAPIProperty(CHARACTER_ENCODING, "UTF-8"); + } + + /** + * {@inheritDoc} + */ + public boolean getAllowMultipleEncoding() { + return getESAPIProperty( ALLOW_MULTIPLE_ENCODING, false ); + } + + /** + * {@inheritDoc} + */ + public boolean getAllowMixedEncoding() { + return getESAPIProperty( ALLOW_MIXED_ENCODING, false ); + } + + /** + * {@inheritDoc} + */ + public List getDefaultCanonicalizationCodecs() { + List def = new ArrayList(); + def.add( "org.owasp.esapi.codecs.HTMLEntityCodec" ); + def.add( "org.owasp.esapi.codecs.PercentCodec" ); + def.add( "org.owasp.esapi.codecs.JavaScriptCodec" ); + return getESAPIProperty( CANONICALIZATION_CODECS, def ); + } + + /** + * {@inheritDoc} + */ + public String getDigitalSignatureAlgorithm() { + return getESAPIProperty(DIGITAL_SIGNATURE_ALGORITHM, "SHAwithDSA"); + } + + /** + * {@inheritDoc} + */ + public int getDigitalSignatureKeyLength() { + return getESAPIProperty(DIGITAL_SIGNATURE_KEY_LENGTH, 2048); + } + + /** + * {@inheritDoc} + */ + public String getRandomAlgorithm() { + return getESAPIProperty(RANDOM_ALGORITHM, "SHA1PRNG"); + } + + /** + * {@inheritDoc} + */ + public int getAllowedLoginAttempts() { + return getESAPIProperty(ALLOWED_LOGIN_ATTEMPTS, 5); + } + + /** + * {@inheritDoc} + */ + public int getMaxOldPasswordHashes() { + return getESAPIProperty(MAX_OLD_PASSWORD_HASHES, 12); + } + + /** + * {@inheritDoc} + */ + public File getUploadDirectory() { + String dir = getESAPIProperty( UPLOAD_DIRECTORY, "UploadDir"); + return new File( dir ); + } + + /** + * {@inheritDoc} + */ + public File getUploadTempDirectory() { + String dir = getESAPIProperty(UPLOAD_TEMP_DIRECTORY, + System.getProperty("java.io.tmpdir","UploadTempDir") + ); + return new File( dir ); + } + + /** + * {@inheritDoc} + */ + public boolean getDisableIntrusionDetection() { + String value = properties.getProperty( DISABLE_INTRUSION_DETECTION ); + if ("true".equalsIgnoreCase(value)) return true; + return false; // Default result + } + + /** + * {@inheritDoc} + */ + public Threshold getQuota(String eventName) { + int count = getESAPIProperty("IntrusionDetector." + eventName + ".count", 0); + int interval = getESAPIProperty("IntrusionDetector." + eventName + ".interval", 0); + List actions = new ArrayList(); + String actionString = getESAPIProperty("IntrusionDetector." + eventName + ".actions", ""); + if (actionString != null) { + String[] actionList = actionString.split(","); + actions = Arrays.asList(actionList); + } + if ( count > 0 && interval > 0 && actions.size() > 0 ) { + return new Threshold(eventName, count, interval, actions); + } + return null; + } + + /** + * {@inheritDoc} + */ + public boolean getLogEncodingRequired() { + return getESAPIProperty( LOG_ENCODING_REQUIRED, false ); + } + + + /** + * {@inheritDoc} + */ + public boolean getLogApplicationName() { + return getESAPIProperty( LOG_APPLICATION_NAME, true ); + } + + + /** + * {@inheritDoc} + */ + public boolean getLogServerIP() { + return getESAPIProperty( LOG_SERVER_IP, true ); + } + + /** + * {@inheritDoc} + */ + public boolean getForceHttpOnlySession() { + return getESAPIProperty( FORCE_HTTPONLYSESSION, true ); + } + + /** + * {@inheritDoc} + */ + public boolean getForceSecureSession() { + return getESAPIProperty( FORCE_SECURESESSION, true ); + } + + /** + * {@inheritDoc} + */ + public boolean getForceHttpOnlyCookies() { + return getESAPIProperty( FORCE_HTTPONLYCOOKIES, true ); + } + + /** + * {@inheritDoc} + */ + public boolean getForceSecureCookies() { + return getESAPIProperty( FORCE_SECURECOOKIES, true ); + } + + /** + * {@inheritDoc} + */ + public int getMaxHttpHeaderSize() { + return getESAPIProperty( MAX_HTTP_HEADER_SIZE, 4096); + } + + /** + * {@inheritDoc} + */ + public String getResponseContentType() { + return getESAPIProperty( RESPONSE_CONTENT_TYPE, "text/html; charset=UTF-8" ); + } + + /** + * {@inheritDoc} + */ + public String getHttpSessionIdName() { + return getESAPIProperty( HTTP_SESSION_ID_NAME, "JSESSIONID" ); + } + + /** + * {@inheritDoc} + */ + public long getRememberTokenDuration() { + int days = getESAPIProperty( REMEMBER_TOKEN_DURATION, 14 ); + return (long) (1000 * 60 * 60 * 24 * days); + } + + /** + * {@inheritDoc} + */ + public int getSessionIdleTimeoutLength() { + int minutes = getESAPIProperty( IDLE_TIMEOUT_DURATION, 20 ); + return 1000 * 60 * minutes; + } + + /** + * {@inheritDoc} + */ + public int getSessionAbsoluteTimeoutLength() { + int minutes = getESAPIProperty(ABSOLUTE_TIMEOUT_DURATION, 20 ); + return 1000 * 60 * minutes; + } + + /** + * getValidationPattern returns a single pattern based upon key + * + * @param key + * validation pattern name you'd like + * @return + * if key exists, the associated validation pattern, null otherwise + */ + public Pattern getValidationPattern( String key ) { + String value = getESAPIProperty( "Validator." + key, "" ); + // check cache + Pattern p = patternCache.get( value ); + if ( p != null ) return p; + + // compile a new pattern + if ( value == null || value.equals( "" ) ) return null; + try { + Pattern q = Pattern.compile(value); + patternCache.put( value, q ); + return q; + } catch ( PatternSyntaxException e ) { + logSpecial( "SecurityConfiguration for " + key + " not a valid regex in ESAPI.properties. Returning null", null ); + return null; + } + } + + /** + * getWorkingDirectory returns the default directory where processes will be executed + * by the Executor. + */ + public File getWorkingDirectory() { + String dir = getESAPIProperty( WORKING_DIRECTORY, System.getProperty( "user.dir") ); + if ( dir != null ) { + return new File( dir ); + } + return null; + } + + /** + * {@inheritDoc} + */ + public String getPreferredJCEProvider() { + return properties.getProperty(PREFERRED_JCE_PROVIDER); // No default! + } + + /** + * {@inheritDoc} + */ + public List getCombinedCipherModes() + { + List empty = new ArrayList(); // Default is empty list + return getESAPIProperty(COMBINED_CIPHER_MODES, empty); + } + + /** + * {@inheritDoc} + */ + public List getAdditionalAllowedCipherModes() + { + List empty = new ArrayList(); // Default is empty list + return getESAPIProperty(ADDITIONAL_ALLOWED_CIPHER_MODES, empty); + } + + /** + * {@inheritDoc} + */ + public boolean getLenientDatesAccepted() { + return getESAPIProperty( ACCEPT_LENIENT_DATES, false); + } + + protected String getESAPIProperty( String key, String def ) { + String value = properties.getProperty(key); + if ( value == null ) { + logSpecial( "SecurityConfiguration for " + key + " not found in ESAPI.properties. Using default: " + def, null ); + return def; + } + return value; + } + + protected boolean getESAPIProperty( String key, boolean def ) { + String property = properties.getProperty(key); + if ( property == null ) { + logSpecial( "SecurityConfiguration for " + key + " not found in ESAPI.properties. Using default: " + def, null ); + return def; + } + if ( property.equalsIgnoreCase("true") || property.equalsIgnoreCase("yes" ) ) { + return true; + } + if ( property.equalsIgnoreCase("false") || property.equalsIgnoreCase( "no" ) ) { + return false; + } + logSpecial( "SecurityConfiguration for " + key + " not either \"true\" or \"false\" in ESAPI.properties. Using default: " + def, null ); + return def; + } + + protected byte[] getESAPIPropertyEncoded( String key, byte[] def ) { + String property = properties.getProperty(key); + if ( property == null ) { + logSpecial( "SecurityConfiguration for " + key + " not found in ESAPI.properties. Using default: " + def, null ); + return def; + } + try { + return ESAPI.encoder().decodeFromBase64(property); + } catch( IOException e ) { + logSpecial( "SecurityConfiguration for " + key + " not properly Base64 encoded in ESAPI.properties. Using default: " + def, null ); + return null; + } + } + + protected int getESAPIProperty( String key, int def ) { + String property = properties.getProperty(key); + if ( property == null ) { + logSpecial( "SecurityConfiguration for " + key + " not found in ESAPI.properties. Using default: " + def, null ); + return def; + } + try { + return Integer.parseInt( property ); + } catch( NumberFormatException e ) { + logSpecial( "SecurityConfiguration for " + key + " not an integer in ESAPI.properties. Using default: " + def, null ); + return def; + } + } + + /** + * Returns a {@code List} representing the parsed, comma-separated property. + * + * @param key The specified property name + * @param def A default value for the property name to return if the property + * is not set. + * @return A list of strings. + */ + protected List getESAPIProperty( String key, List def ) { + String property = properties.getProperty( key ); + if ( property == null ) { + logSpecial( "SecurityConfiguration for " + key + " not found in ESAPI.properties. Using default: " + def, null ); + return def; + } + String[] parts = property.split(","); + return Arrays.asList( parts ); + } + + /** + * {@inheritDoc} + * Looks for property in three configuration files in following order: + * 1.) In file defined as org.owasp.esapi.opsteam system property + * 2.) In file defined as org.owasp.esapi.devteam system property + * 3.) In ESAPI.properties + */ + @Override + public int getIntProp(String propertyName) throws ConfigurationException { + try { + return esapiPropertyManager.getIntProp(propertyName); + } catch (ConfigurationException ex) { + String property = properties.getProperty(propertyName); + try { + return Integer.parseInt(property); + } catch (NumberFormatException e) { + throw new ConfigurationException( "SecurityConfiguration for " + propertyName + " has incorrect " + + "type"); + } + } + } + + /** + * {@inheritDoc} + * Looks for property in three configuration files in following order: + * 1.) In file defined as org.owasp.esapi.opsteam system property + * 2.) In file defined as org.owasp.esapi.devteam system property + * 3.) In ESAPI.properties + */ + @Override + public byte[] getByteArrayProp(String propertyName) throws ConfigurationException { + try { + return esapiPropertyManager.getByteArrayProp(propertyName); + } catch (ConfigurationException ex) { + String property = properties.getProperty(propertyName); + if ( property == null ) { + throw new ConfigurationException( "SecurityConfiguration for " + propertyName + " not found in ESAPI.properties"); + } + try { + return ESAPI.encoder().decodeFromBase64(property); + } catch( IOException e ) { + throw new ConfigurationException( "SecurityConfiguration for " + propertyName + " has incorrect " + + "type"); + } + } + } + + /** + * {@inheritDoc} + * Looks for property in three configuration files in following order: + * 1.) In file defined as org.owasp.esapi.opsteam system property + * 2.) In file defined as org.owasp.esapi.devteam system property + * 3.) In ESAPI.properties + */ + @Override + public Boolean getBooleanProp(String propertyName) throws ConfigurationException { + try { + return esapiPropertyManager.getBooleanProp(propertyName); + } catch (ConfigurationException ex) { + String property = properties.getProperty(propertyName); + if ( property == null ) { + throw new ConfigurationException( "SecurityConfiguration for " + propertyName + " not found in ESAPI.properties"); + } + if ( property.equalsIgnoreCase("true") || property.equalsIgnoreCase("yes") ) { + return true; + } + if ( property.equalsIgnoreCase("false") || property.equalsIgnoreCase("no") ) { + return false; + } + throw new ConfigurationException( "SecurityConfiguration for " + propertyName + " has incorrect " + + "type"); + } + } + + /** + * {@inheritDoc} + * Looks for property in three configuration files in following order: + * 1.) In file defined as org.owasp.esapi.opsteam system property + * 2.) In file defined as org.owasp.esapi.devteam system property + * 3.) In ESAPI.properties + */ + @Override + public String getStringProp(String propertyName) throws ConfigurationException { + try { + return esapiPropertyManager.getStringProp(propertyName); + } catch (ConfigurationException ex) { + String property = properties.getProperty( propertyName ); + if ( property == null ) { + throw new ConfigurationException( "SecurityConfiguration for " + propertyName + " not found in ESAPI.properties"); + } + return property; + } + } + + + protected boolean shouldPrintProperties() { + return getESAPIProperty(PRINT_PROPERTIES_WHEN_LOADED, false); + } + + protected Properties getESAPIProperties() { + return properties; + } +} diff --git a/src/main/java/org/owasp/esapi/reference/DefaultUser.java b/src/main/java/org/owasp/esapi/reference/DefaultUser.java new file mode 100644 index 000000000..c9065427b --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/DefaultUser.java @@ -0,0 +1,608 @@ +/** + * 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.reference; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.EncoderConstants; +import org.owasp.esapi.HTTPUtilities; +import org.owasp.esapi.Logger; +import org.owasp.esapi.User; +import org.owasp.esapi.errors.*; + +import javax.servlet.http.HttpSession; +import java.io.Serializable; +import java.util.Set; +import java.util.HashSet; +import java.util.Date; +import java.util.Locale; +import java.util.Collections; +import java.util.HashMap; +/** + * Reference implementation of the User interface. This implementation is serialized into a flat file in a simple format. + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @author Chris Schmidt (chrisisbeef .at. gmail.com) Digital Ritual Software + * @since June 1, 2007 + * @see org.owasp.esapi.User + */ +public class DefaultUser implements User, Serializable { + + /** The Constant serialVersionUID. */ + private static final long serialVersionUID = 1L; + + /** The idle timeout length specified in the ESAPI config file. */ + private static final int IDLE_TIMEOUT_LENGTH = ESAPI.securityConfiguration().getSessionIdleTimeoutLength(); + + /** The absolute timeout length specified in the ESAPI config file. */ + private static final int ABSOLUTE_TIMEOUT_LENGTH = ESAPI.securityConfiguration().getSessionAbsoluteTimeoutLength(); + + /** The logger used by the class. */ + private transient final Logger logger = ESAPI.getLogger("DefaultUser"); + + /** This user's account id. */ + long accountId = 0; + + /** This user's account name. */ + private String accountName = ""; + + /** This user's screen name (account name alias). */ + private String screenName = ""; + + /** This user's CSRF token. */ + private String csrfToken = resetCSRFToken(); + + /** This user's assigned roles. */ + private Set roles = new HashSet(); + + /** Whether this user's account is locked. */ + private boolean locked = false; + + /** Whether this user is logged in. */ + private boolean loggedIn = true; + + /** Whether this user's account is enabled. */ + private boolean enabled = false; + + /** The last host address used by this user. */ + private String lastHostAddress; + + /** The last password change time for this user. */ + private Date lastPasswordChangeTime = new Date(0); + + /** The last login time for this user. */ + private Date lastLoginTime = new Date(0); + + /** The last failed login time for this user. */ + private Date lastFailedLoginTime = new Date(0); + + /** The expiration date/time for this user's account. */ + private Date expirationTime = new Date(Long.MAX_VALUE); + + /** The sessions this user is associated with */ + private transient Set sessions = new HashSet(); + + /** The event map for this User */ + private transient HashMap eventMap = new HashMap(); + + /* A flag to indicate that the password must be changed before the account can be used. */ + // private boolean requiresPasswordChange = true; + + /** The failed login count for this user's account. */ + private int failedLoginCount = 0; + + /** This user's Locale. */ + private Locale locale; + + private static final int MAX_ROLE_LENGTH = 250; + + /** + * Instantiates a new user. + * + * @param accountName + * The name of this user's account. + */ + public DefaultUser(String accountName) { + this.accountName = accountName.toLowerCase(); + while( true ) { + long id = Math.abs( ESAPI.randomizer().getRandomLong() ); + if ( ESAPI.authenticator().getUser( id ) == null && id != 0 ) { + this.accountId = id; + break; + } + } + } + + /** + * {@inheritDoc} + */ + public void addRole(String role) throws AuthenticationException { + String roleName = role.toLowerCase(); + if ( ESAPI.validator().isValidInput("addRole", roleName, "RoleName", MAX_ROLE_LENGTH, false) ) { + roles.add(roleName); + logger.info(Logger.SECURITY_SUCCESS, "Role " + roleName + " added to " + getAccountName() ); + } else { + throw new AuthenticationAccountsException( "Add role failed", "Attempt to add invalid role " + roleName + " to " + getAccountName() ); + } + } + + /** + * {@inheritDoc} + */ + public void addRoles(Set newRoles) throws AuthenticationException { + for (String newRole : newRoles) + { + addRole(newRole); + } + } + + /** + * {@inheritDoc} + */ + public void changePassword(String oldPassword, String newPassword1, String newPassword2) throws AuthenticationException, EncryptionException { + ESAPI.authenticator().changePassword(this, oldPassword, newPassword1, newPassword2); + } + + /** + * {@inheritDoc} + */ + public void disable() { + enabled = false; + logger.info( Logger.SECURITY_SUCCESS, "Account disabled: " + getAccountName() ); + } + + /** + * {@inheritDoc} + */ + public void enable() { + this.enabled = true; + logger.info( Logger.SECURITY_SUCCESS, "Account enabled: " + getAccountName() ); + } + + /** + * {@inheritDoc} + */ + public long getAccountId() { + return accountId; + } + + /** + * {@inheritDoc} + */ + public String getAccountName() { + return accountName; + } + + /** + * {@inheritDoc} + */ + public String getCSRFToken() { + return csrfToken; + } + + /** + * {@inheritDoc} + */ + public Date getExpirationTime() { + return (Date)expirationTime.clone(); + } + + /** + * {@inheritDoc} + */ + public int getFailedLoginCount() { + return failedLoginCount; + } + + /** + * Set the failed login count + * + * @param count + * the number of failed logins + */ + void setFailedLoginCount(int count) { + failedLoginCount = count; + } + + /** + * {@inheritDoc} + */ + public Date getLastFailedLoginTime() { + return (Date)lastFailedLoginTime.clone(); + } + + /** + * {@inheritDoc} + */ + public String getLastHostAddress() { + if ( lastHostAddress == null ) { + return "unknown"; + } + return lastHostAddress; + } + + /** + * {@inheritDoc} + */ + public Date getLastLoginTime() { + return (Date)lastLoginTime.clone(); + } + + /** + * {@inheritDoc} + */ + public Date getLastPasswordChangeTime() { + return (Date)lastPasswordChangeTime.clone(); + } + + /** + * {@inheritDoc} + */ + public String getName() { + return this.getAccountName(); + } + + /** + * {@inheritDoc} + */ + public Set getRoles() { + return Collections.unmodifiableSet(roles); + } + + /** + * {@inheritDoc} + */ + public String getScreenName() { + return screenName; + } + + /** + * {@inheritDoc} + */ + public void addSession( HttpSession s ) { + sessions.add( s ); + } + + /** + * {@inheritDoc} + */ + public void removeSession( HttpSession s ) { + sessions.remove( s ); + } + + /** + * {@inheritDoc} + */ + public Set getSessions() { + return sessions; + } + + /** + * {@inheritDoc} + */ + public void incrementFailedLoginCount() { + failedLoginCount++; + } + + /** + * {@inheritDoc} + */ + public boolean isAnonymous() { + // User cannot be anonymous, since we have a special User.ANONYMOUS instance + // for the anonymous user + return false; + } + + /** + * {@inheritDoc} + */ + public boolean isEnabled() { + return enabled; + } + + /** + * {@inheritDoc} + */ + public boolean isExpired() { + return getExpirationTime().before( new Date() ); + + // If expiration should happen automatically or based on lastPasswordChangeTime? + // long from = lastPasswordChangeTime.getTime(); + // long to = new Date().getTime(); + // double difference = to - from; + // long days = Math.round((difference / (1000 * 60 * 60 * 24))); + // return days > 60; + } + + /** + * {@inheritDoc} + */ + public boolean isInRole(String role) { + return roles.contains(role.toLowerCase()); + } + + /** + * {@inheritDoc} + */ + public boolean isLocked() { + return locked; + } + + /** + * {@inheritDoc} + */ + public boolean isLoggedIn() { + return loggedIn; + } + + /** + * {@inheritDoc} + */ + public boolean isSessionAbsoluteTimeout() { + HttpSession session = ESAPI.httpUtilities().getCurrentRequest().getSession(false); + if ( session == null ) return true; + Date deadline = new Date( session.getCreationTime() + ABSOLUTE_TIMEOUT_LENGTH); + Date now = new Date(); + return now.after(deadline); + } + + /** + * {@inheritDoc} + */ + public boolean isSessionTimeout() { + HttpSession session = ESAPI.httpUtilities().getCurrentRequest().getSession(false); + if ( session == null ) return true; + Date deadline = new Date( session.getLastAccessedTime() + IDLE_TIMEOUT_LENGTH); + Date now = new Date(); + return now.after(deadline); + } + + /** + * {@inheritDoc} + */ + public void lock() { + this.locked = true; + logger.info(Logger.SECURITY_SUCCESS, "Account locked: " + getAccountName() ); + } + + /** + * {@inheritDoc} + */ + public void loginWithPassword(String password) throws AuthenticationException { + if ( password == null || password.equals("") ) { + setLastFailedLoginTime(new Date()); + incrementFailedLoginCount(); + throw new AuthenticationLoginException( "Login failed", "Missing password: " + accountName ); + } + + // don't let disabled users log in + if ( !isEnabled() ) { + setLastFailedLoginTime(new Date()); + incrementFailedLoginCount(); + throw new AuthenticationLoginException("Login failed", "Disabled user attempt to login: " + accountName ); + } + + // don't let locked users log in + if ( isLocked() ) { + setLastFailedLoginTime(new Date()); + incrementFailedLoginCount(); + throw new AuthenticationLoginException("Login failed", "Locked user attempt to login: " + accountName ); + } + + // don't let expired users log in + if ( isExpired() ) { + setLastFailedLoginTime(new Date()); + incrementFailedLoginCount(); + throw new AuthenticationLoginException("Login failed", "Expired user attempt to login: " + accountName ); + } + + logout(); + + if ( verifyPassword( password ) ) { + loggedIn = true; + ESAPI.httpUtilities().changeSessionIdentifier( ESAPI.currentRequest() ); + ESAPI.authenticator().setCurrentUser(this); + setLastLoginTime(new Date()); + setLastHostAddress( ESAPI.httpUtilities().getCurrentRequest().getRemoteAddr() ); + logger.trace(Logger.SECURITY_SUCCESS, "User logged in: " + accountName ); + } else { + loggedIn = false; + setLastFailedLoginTime(new Date()); + incrementFailedLoginCount(); + if (getFailedLoginCount() >= ESAPI.securityConfiguration().getAllowedLoginAttempts()) { + lock(); + } + throw new AuthenticationLoginException("Login failed", "Incorrect password provided for " + getAccountName() ); + } + } + + + /** + * {@inheritDoc} + */ + public void logout() { + ESAPI.httpUtilities().killCookie( ESAPI.currentRequest(), ESAPI.currentResponse(), HTTPUtilities.REMEMBER_TOKEN_COOKIE_NAME ); + + HttpSession session = ESAPI.currentRequest().getSession(false); + if (session != null) { + removeSession(session); + session.invalidate(); + } + ESAPI.httpUtilities().killCookie(ESAPI.currentRequest(), ESAPI.currentResponse(), ESAPI.securityConfiguration().getHttpSessionIdName()); + loggedIn = false; + logger.info(Logger.SECURITY_SUCCESS, "Logout successful" ); + ESAPI.authenticator().setCurrentUser(User.ANONYMOUS); + } + + /** + * {@inheritDoc} + */ + public void removeRole(String role) { + roles.remove(role.toLowerCase()); + logger.trace(Logger.SECURITY_SUCCESS, "Role " + role + " removed from " + getAccountName() ); + } + + /** + * {@inheritDoc} + * + * 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. + * + * @return the string + */ + public String resetCSRFToken() { + // user.csrfToken = ESAPI.encryptor().hash( session.getId(),user.name ); + // user.csrfToken = ESAPI.encryptor().encrypt( address + ":" + ESAPI.encryptor().getTimeStamp(); + csrfToken = ESAPI.randomizer().getRandomString(8, EncoderConstants.CHAR_ALPHANUMERICS); + return csrfToken; + } + + /** + * Sets the account id for this user's account. + */ + private void setAccountId(long accountId) { + this.accountId = accountId; + } + + + /** + * {@inheritDoc} + */ + public void setAccountName(String accountName) { + String old = getAccountName(); + this.accountName = accountName.toLowerCase(); + if (old != null) { + if ( old.equals( "" ) ) { + old = "[nothing]"; + } + logger.info(Logger.SECURITY_SUCCESS, "Account name changed from " + old + " to " + getAccountName() ); + } + } + + /** + * {@inheritDoc} + */ + public void setExpirationTime(Date expirationTime) { + this.expirationTime = new Date( expirationTime.getTime() ); + logger.info(Logger.SECURITY_SUCCESS, "Account expiration time set to " + expirationTime + " for " + getAccountName() ); + } + + /** + * {@inheritDoc} + */ + public void setLastFailedLoginTime(Date lastFailedLoginTime) { + this.lastFailedLoginTime = lastFailedLoginTime; + logger.info(Logger.SECURITY_SUCCESS, "Set last failed login time to " + lastFailedLoginTime + " for " + getAccountName() ); + } + + /** + * {@inheritDoc} + */ + public void setLastHostAddress(String remoteHost) throws AuthenticationHostException + { + if ( lastHostAddress != null && !lastHostAddress.equals(remoteHost)) { + // returning remote address not remote hostname to prevent DNS lookup + throw new AuthenticationHostException("Host change", "User session just jumped from " + lastHostAddress + " to " + remoteHost ); + } + lastHostAddress = remoteHost; + } + + /** + * {@inheritDoc} + */ + public void setLastLoginTime(Date lastLoginTime) { + this.lastLoginTime = lastLoginTime; + logger.info(Logger.SECURITY_SUCCESS, "Set last successful login time to " + lastLoginTime + " for " + getAccountName() ); + } + + /** + * {@inheritDoc} + */ + public void setLastPasswordChangeTime(Date lastPasswordChangeTime) { + this.lastPasswordChangeTime = lastPasswordChangeTime; + logger.info(Logger.SECURITY_SUCCESS, "Set last password change time to " + lastPasswordChangeTime + " for " + getAccountName() ); + } + + /** + * {@inheritDoc} + */ + public void setRoles(Set roles) throws AuthenticationException { + this.roles = new HashSet(); + addRoles(roles); + logger.info(Logger.SECURITY_SUCCESS, "Adding roles " + roles + " to " + getAccountName() ); + } + + /** + * {@inheritDoc} + */ + public void setScreenName(String screenName) { + this.screenName = screenName; + logger.info(Logger.SECURITY_SUCCESS, "ScreenName changed to " + screenName + " for " + getAccountName() ); + } + + /** + * {@inheritDoc} + */ + public String toString() { + return "USER:" + accountName; + } + + /** + * {@inheritDoc} + */ + public void unlock() { + this.locked = false; + this.failedLoginCount = 0; + logger.info( Logger.SECURITY_SUCCESS, "Account unlocked: " + getAccountName() ); + } + + /** + * {@inheritDoc} + */ + public boolean verifyPassword(String password) { + return ESAPI.authenticator().verifyPassword(this, password); + } + + /** + * Override clone and make final to prevent duplicate user objects. + * @return Nothing, as clone() is not supported for this class. A CloneNotSupportedException is always thrown for this class. + * @throws java.lang.CloneNotSupportedException + */ + public final Object clone() throws java.lang.CloneNotSupportedException { + throw new java.lang.CloneNotSupportedException(); + } + /** + * @return the locale + */ + public Locale getLocale() { + return locale; + } + + /** + * @param locale the locale to set + */ + public void setLocale(Locale locale) { + this.locale = locale; + } + + public HashMap getEventMap() { + return eventMap; + } + +} diff --git a/src/main/java/org/owasp/esapi/reference/DefaultValidator.java b/src/main/java/org/owasp/esapi/reference/DefaultValidator.java new file mode 100644 index 000000000..a458f40db --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/DefaultValidator.java @@ -0,0 +1,1387 @@ +/** + * 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 + * @author Jim Manico (jim@manico.net) Manico.net + * + * @created 2007 + */ +package org.owasp.esapi.reference; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.text.DateFormat; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Encoder; +import org.owasp.esapi.Logger; +import org.owasp.esapi.SecurityConfiguration; +import org.owasp.esapi.ValidationErrorList; +import org.owasp.esapi.ValidationRule; +import org.owasp.esapi.Validator; +import org.owasp.esapi.errors.IntrusionException; +import org.owasp.esapi.errors.ValidationAvailabilityException; +import org.owasp.esapi.errors.ValidationException; +import org.owasp.esapi.reference.validation.CreditCardValidationRule; +import org.owasp.esapi.reference.validation.DateValidationRule; +import org.owasp.esapi.reference.validation.HTMLValidationRule; +import org.owasp.esapi.reference.validation.IntegerValidationRule; +import org.owasp.esapi.reference.validation.NumberValidationRule; +import org.owasp.esapi.reference.validation.StringValidationRule; + +/** + * Reference implementation of the {@code Validator} interface. This implementation + * relies on the ESAPI {@code Encoder}, {@link java.util.regex.Pattern}, + * {@link java.util.Date}, + * and several other classes to provide basic validation functions. This library + * has a heavy emphasis on allow-list validation and canonicalization. + *

+ * A Note about Canonicalization: + * The behaviors of objects of this class are largely driven by how the + * associated {@code Encoder} is created and passed to one of this + * class' constructors. Specifically, what {@link org.owasp.esapi.codecs.Codec} + * types are referenced by the {@link org.owasp.esapi.Encoder} instance + * associated with this particular {@code DefaultValidator} instance. In places + * where the default {@code Encoder} instance is used, the behavior is driven + * by three ESAPI properties as defined in the ESAPI.properties file. + * These property names and their default values (as delivered in ESAPI's + * "configuration" jar) are as follows: + *

+ * Encoder.AllowMultipleEncoding=false
+ * Encoder.AllowMixedEncoding=false
+ * Encoder.DefaultCodecList=HTMLEntityCodec,PercentCodec,JavaScriptCodec
+ * 
+ * In places where canonicalization is checked, multiple + * encoding (the first property, which refers to encoding in the same manner + * more than once) or mixed encoding (the second property, which refers to + * encoding using multiple different encoding mechanisms) are generally + * considered attacks unless these respective property values are set to + * "true". + *

+ * Note that changing any of these three properties may affect the behavior as + * documented in this class' methods. + *

+ * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @author Jim Manico (jim@manico.net) Manico.net + * @author Matt Seil (mseil .at. acm.org) + * + * @since June 1, 2007 + * @see org.owasp.esapi.Validator + * @see org.owasp.esapi.Encoder + * @see org.owasp.esapi.Encoder#canonicalize(String,boolean,boolean) + */ +public class DefaultValidator implements org.owasp.esapi.Validator { + private static Logger logger = ESAPI.log(); + private static volatile Validator instance = null; + private static boolean alreadyLogged = false; + + public static Validator getInstance() { + if ( instance == null ) { + synchronized ( Validator.class ) { + if ( instance == null ) { + instance = new DefaultValidator(); + } + } + } + return instance; + } + + /** A map of validation rules */ + private Map rules = new HashMap(); + + /** The encoder to use for canonicalization */ + private Encoder encoder = null; + + /** The encoder to use for file system */ + private static Validator fileValidator = null; + + /* Initialize file validator with an appropriate set of codecs */ + static { + List list = new ArrayList(); + list.add( "HTMLEntityCodec" ); + list.add( "PercentCodec" ); + Encoder fileEncoder = new DefaultEncoder( list ); + fileValidator = new DefaultValidator( fileEncoder ); + } + + + /** + * Default constructor uses the ESAPI standard encoder for canonicalization. + * This uses an {@code Encoder} created based on the {@code Codec}s + * specified by the value of the {@code Encoder.DefaultCodecList} ESAPI + * property as defined in your ESAPI.properties file. + */ + public DefaultValidator() { + this.encoder = ESAPI.encoder(); + } + + /** + * Construct a new DefaultValidator that will use the specified + * {@code Encoder} for canonicalization. + * @param encoder The specially constructed ESAPI {@code Encoder} instance + * that uses a custom list of {@code Codec}s for + * canonicalization purposes. See + * {@link org.owasp.esapi.Encoder#canonicalize(String,boolean,boolean)} + * for an example of how to create a custom {@code Encoder}. + */ + public DefaultValidator( Encoder encoder ) { + this.encoder = encoder; + } + + + /** + * {@inheritDoc} + */ + @Override + public void addRule(ValidationRule rule ) { + rules.put( rule.getTypeName(), rule ); + } + + /** + * {@inheritDoc} + */ + @Override + public ValidationRule getRule(String name ) { + return rules.get( name ); + } + + + /** + * {@inheritDoc} + *

+ * Double encoding is treated as an attack. + * The canonicalization behavior is controlled by the instance's associated ESAPI + * {@code Encoder} and generally driven through the ESAPI property + * {@code Encoder.DefaultCodecList} specified in the ESAPI.properties + * file. See the class level documentation section "A Note about Canonicalization" + * for additional details. + */ + @Override + public boolean isValidInput(String context, String input, String type, int maxLength, boolean allowNull) throws IntrusionException { + return isValidInput(context, input, type, maxLength, allowNull, true); + } + + /** + * {@inheritDoc} + *

+ * Double encoding is treated as an attack. + * The canonicalization behavior is controlled by the instance's associated ESAPI + * {@code Encoder} and generally driven through the ESAPI property + * {@code Encoder.DefaultCodecList} specified in the ESAPI.properties + * file. See the class level documentation section "A Note about Canonicalization" + * for additional details. + */ + @Override + public boolean isValidInput(String context, String input, String type, int maxLength, boolean allowNull, ValidationErrorList errors) { + return isValidInput(context, input, type, maxLength, allowNull, true, errors); + } + + /** + * {@inheritDoc} + *

+ * Double encoding is treated as an attack. + * The canonicalization behavior is controlled by the instance's associated ESAPI + * {@code Encoder} and generally driven through the ESAPI property + * {@code Encoder.DefaultCodecList} specified in the ESAPI.properties + * file. See the class level documentation section "A Note about Canonicalization" + * for additional details. + *

+ * This implementation does not throw {@link IntrusionException}. + */ + @Override + public boolean isValidInput(String context, String input, String type, int maxLength, boolean allowNull, boolean canonicalize) { + try { + getValidInput( context, input, type, maxLength, allowNull, canonicalize); + return true; + } catch( Exception e ) { + return false; + } + } + + /** + * {@inheritDoc} + *

+ * Double encoding is treated as an attack. + * The canonicalization behavior is controlled by the instance's associated ESAPI + * {@code Encoder} and generally driven through the ESAPI property + * {@code Encoder.DefaultCodecList} specified in the ESAPI.properties + * file. See the class level documentation section "A Note about Canonicalization" + * for additional details. + */ + @Override + public boolean isValidInput(String context, String input, String type, int maxLength, boolean allowNull, boolean canonicalize, ValidationErrorList errors) throws IntrusionException { + try { + getValidInput( context, input, type, maxLength, allowNull, canonicalize); + return true; + } catch( ValidationException e ) { + errors.addError( context, e ); + return false; + } + } + + /** + * {@inheritDoc} + *

+ * Double encoding is treated as an attack. + * The canonicalization behavior is controlled by the instance's associated ESAPI + * {@code Encoder} and generally driven through the ESAPI property + * {@code Encoder.DefaultCodecList} specified in the ESAPI.properties + * file. See the class level documentation section "A Note about Canonicalization" + * for additional details. + */ + @Override + public String getValidInput(String context, String input, String type, int maxLength, boolean allowNull) throws ValidationException { + return getValidInput(context, input, type, maxLength, allowNull, true); + } + + /** + * {@inheritDoc} + *

+ * Double encoding is treated as an attack. + * The canonicalization behavior is controlled by the instance's associated ESAPI + * {@code Encoder} and generally driven through the ESAPI property + * {@code Encoder.DefaultCodecList} specified in the ESAPI.properties + * file. See the class level documentation section "A Note about Canonicalization" + * for additional details. + */ + @Override + public String getValidInput(String context, String input, String type, int maxLength, boolean allowNull, boolean canonicalize) throws ValidationException { + StringValidationRule rvr = new StringValidationRule( type, encoder ); + Pattern p = ESAPI.securityConfiguration().getValidationPattern( type ); + if ( p != null ) { + rvr.addWhitelistPattern( p ); + } else { + // Issue 232 - Specify requested type in exception message - CS + throw new IllegalArgumentException("The selected type [" + type + "] was not set via the ESAPI validation configuration"); + } + rvr.setMaximumLength(maxLength); + rvr.setAllowNull(allowNull); + rvr.setCanonicalize(canonicalize); + return rvr.getValid(context, input); + } + + /** + * {@inheritDoc} + *

+ * Double encoding is treated as an attack. + * The canonicalization behavior is controlled by the instance's associated ESAPI + * {@code Encoder} and generally driven through the ESAPI property + * {@code Encoder.DefaultCodecList} specified in the ESAPI.properties + * file. See the class level documentation section "A Note about Canonicalization" + * for additional details. + */ + @Override + public String getValidInput(String context, String input, String type, int maxLength, boolean allowNull, ValidationErrorList errors) throws IntrusionException { + return getValidInput(context, input, type, maxLength, allowNull, true, errors); + } + + /** + * {@inheritDoc} + *

+ * Double encoding is treated as an attack. + * The canonicalization behavior is controlled by the instance's associated ESAPI + * {@code Encoder} and generally driven through the ESAPI property + * {@code Encoder.DefaultCodecList} specified in the ESAPI.properties + * file. See the class level documentation section "A Note about Canonicalization" + * for additional details. + */ + @Override + public String getValidInput(String context, String input, String type, int maxLength, boolean allowNull, boolean canonicalize, ValidationErrorList errors) throws IntrusionException { + try { + return getValidInput(context, input, type, maxLength, allowNull, canonicalize); + } catch (ValidationException e) { + errors.addError(context, e); + } + + return ""; + } + + /** + * {@inheritDoc} + *

+ * This implementation does not throw {@link IntrusionException}. + */ + @Override + public boolean isValidDate(String context, String input, DateFormat format, boolean allowNull) { + try { + getValidDate( context, input, format, allowNull); + return true; + } catch( Exception e ) { + return false; + } + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isValidDate(String context, String input, DateFormat format, boolean allowNull, ValidationErrorList errors) throws IntrusionException { + getValidDate( context, input, format, allowNull, errors); + return errors.isEmpty(); + } + + /** + * {@inheritDoc} + */ + @Override + public Date getValidDate(String context, String input, DateFormat format, boolean allowNull) throws ValidationException, IntrusionException { + + ValidationErrorList vel = new ValidationErrorList(); + Date validDate = getValidDate(context, input, format, allowNull, vel); + + if (vel.isEmpty()) { + return validDate; + } + + throw vel.errors().get(0); + } + + /** + * {@inheritDoc} + */ + @Override + public Date getValidDate(String context, String input, DateFormat format, boolean allowNull, ValidationErrorList errors) throws IntrusionException { + DateValidationRule dvr = new DateValidationRule( "SimpleDate", encoder, format); + dvr.setAllowNull(allowNull); + Date safeDate = dvr.sanitize(context, input, errors); + if (!errors.isEmpty()) { + safeDate = null; + } + // error has been added to list, so return null + return safeDate; + } + + /** + * {@inheritDoc} + *

+ * This implementation relies on the OWASP AntiSamy project. + */ + @Override + public String getValidSafeHTML(String context, String input, int maxLength, boolean allowNull ) throws ValidationException, IntrusionException { + HTMLValidationRule hvr = new HTMLValidationRule( "safehtml", encoder ); + hvr.setMaximumLength(maxLength); + hvr.setAllowNull(allowNull); + return hvr.getValid(context, input); + } + + /** + * {@inheritDoc} + */ + @Override + public String getValidSafeHTML(String context, String input, int maxLength, boolean allowNull, ValidationErrorList errors) throws IntrusionException { + try { + return getValidSafeHTML(context, input, maxLength, allowNull); + } catch (ValidationException e) { + errors.addError(context, e); + } + + return ""; + } + + /** + * {@inheritDoc} + *

+ * This implementation does not throw {@link IntrusionException}. + */ + @Override + public boolean isValidCreditCard(String context, String input, boolean allowNull) { + try { + getValidCreditCard( context, input, allowNull); + return true; + } catch( Exception e ) { + return false; + } + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isValidCreditCard(String context, String input, boolean allowNull, ValidationErrorList errors) throws IntrusionException { + try { + getValidCreditCard( context, input, allowNull); + return true; + } catch( ValidationException e ) { + errors.addError(context, e); + return false; + } + } + + /** + * {@inheritDoc} + */ + @Override + public String getValidCreditCard(String context, String input, boolean allowNull) throws ValidationException, IntrusionException { + CreditCardValidationRule ccvr = new CreditCardValidationRule( "creditcard", encoder ); + ccvr.setAllowNull(allowNull); + return ccvr.getValid(context, input); + } + + /** + * {@inheritDoc} + */ + @Override + public String getValidCreditCard(String context, String input, boolean allowNull, ValidationErrorList errors) throws IntrusionException { + try { + return getValidCreditCard(context, input, allowNull); + } catch (ValidationException e) { + errors.addError(context, e); + } + + return ""; + } + + /** + * {@inheritDoc} + * + *

Note: On platforms that support symlinks, this function will fail canonicalization if directorypath + * is a symlink. For example, on MacOS X, /etc is actually /private/etc. If you mean to use /etc, use its real + * path (/private/etc), not the symlink (/etc).

+ *

+ * This implementation does not throw {@link IntrusionException}. + */ + @Override + public boolean isValidDirectoryPath(String context, String input, File parent, boolean allowNull) { + try { + getValidDirectoryPath( context, input, parent, allowNull); + return true; + } catch( Exception e ) { + return false; + } + } + + /** + * {@inheritDoc} + * + *

Note: On platforms that support symlinks, this function will fail canonicalization if directorypath + * is a symlink. For example, on MacOS X, /etc is actually /private/etc. If you mean to use /etc, use its real + * path (/private/etc), not the symlink (/etc).

+ */ + @Override + public boolean isValidDirectoryPath(String context, String input, File parent, boolean allowNull, ValidationErrorList errors) throws IntrusionException { + try { + getValidDirectoryPath( context, input, parent, allowNull); + return true; + } catch( ValidationException e ) { + errors.addError(context, e); + return false; + } + } + + /** + * {@inheritDoc} + * + *

Note: On platforms that support symlinks, this function will fail canonicalization if directorypath + * is a symlink. For example, on MacOS X, /etc is actually /private/etc. If you mean to use /etc, use its real + * path (/private/etc), not the symlink (/etc).

+ */ + @Override + public String getValidDirectoryPath(String context, String input, File parent, 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.getCanonicalFile().toPath().startsWith( parent.getCanonicalFile().toPath() ) ) { // Fixes GHSL-2022-008 + 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 ); + } + } + + /** + * {@inheritDoc} + * + *

Note: On platforms that support symlinks, this function will fail canonicalization if directorypath + * is a symlink. For example, on MacOS X, /etc is actually /private/etc. If you mean to use /etc, use its real + * path (/private/etc), not the symlink (/etc).

+ */ + @Override + public String getValidDirectoryPath(String context, String input, File parent, boolean allowNull, ValidationErrorList errors) throws IntrusionException { + + try { + return getValidDirectoryPath(context, input, parent, allowNull); + } catch (ValidationException e) { + errors.addError(context, e); + } + + return ""; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isValidFileName(String context, String input, boolean allowNull) throws IntrusionException { + return isValidFileName( context, input, ESAPI.securityConfiguration().getAllowedFileExtensions(), allowNull ); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isValidFileName(String context, String input, boolean allowNull, ValidationErrorList errors) throws IntrusionException { + return isValidFileName( context, input, ESAPI.securityConfiguration().getAllowedFileExtensions(), allowNull, errors ); + } + + /** + * {@inheritDoc} + *

+ * This implementation does not throw {@link IntrusionException}. + */ + @Override + public boolean isValidFileName(String context, String input, List allowedExtensions, boolean allowNull) { + try { + getValidFileName( context, input, allowedExtensions, allowNull); + return true; + } catch( Exception e ) { + return false; + } + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isValidFileName(String context, String input, List allowedExtensions, boolean allowNull, ValidationErrorList errors) throws IntrusionException { + try { + getValidFileName( context, input, allowedExtensions, allowNull); + return true; + } catch( ValidationException e ) { + errors.addError(context, e); + return false; + } + } + + /** + * {@inheritDoc} + */ + @Override + public String getValidFileName(String context, String input, List allowedExtensions, boolean allowNull) throws ValidationException, IntrusionException { + if ((allowedExtensions == null) || (allowedExtensions.isEmpty())) { + throw new ValidationException( "Internal Error", "getValidFileName called with an empty or null list of allowed Extensions, therefore no files can be uploaded" ); + } + + String canonical = ""; + // detect path manipulation + try { + if (isEmpty(input)) { + if (allowNull) { + return null; + } + throw new ValidationException( context + ": Input file name required", "Input required: context=" + context + ", input=" + input, context ); + } + + // do basic validation + canonical = new File(input).getCanonicalFile().getName(); + getValidInput( context, input, "FileName", 255, true ); + + File f = new File(canonical); + String c = f.getCanonicalPath(); + String cpath = c.substring(c.lastIndexOf(File.separator) + 1); + + + // the path is valid if the input matches the canonical path + if (!input.equals(cpath)) { + throw new ValidationException( context + ": Invalid file name", "Invalid directory name does not match the canonical path: context=" + context + ", input=" + input + ", canonical=" + canonical, context ); + } + + } catch (IOException e) { + throw new ValidationException( context + ": Invalid file name", "Invalid file name does not exist: context=" + context + ", canonical=" + canonical, e, context ); + } + + // verify extensions + Iterator i = allowedExtensions.iterator(); + while (i.hasNext()) { + String ext = i.next(); + if (input.toLowerCase().endsWith(ext.toLowerCase())) { + return canonical; + } + } + throw new ValidationException( context + ": Invalid file name does not have valid extension ( "+allowedExtensions+")", "Invalid file name does not have valid extension ( "+allowedExtensions+"): context=" + context+", input=" + input, context ); + } + + /** + * {@inheritDoc} + */ + @Override + public String getValidFileName(String context, String input, List allowedParameters, boolean allowNull, ValidationErrorList errors) throws IntrusionException { + try { + return getValidFileName(context, input, allowedParameters, allowNull); + } catch (ValidationException e) { + errors.addError(context, e); + } + + return ""; + } + + /** + * {@inheritDoc} + *

+ * This implementation does not throw {@link IntrusionException}. + */ + @Override + public boolean isValidNumber(String context, String input, long minValue, long maxValue, boolean allowNull) { + try { + getValidNumber(context, input, minValue, maxValue, allowNull); + return true; + } catch( Exception e ) { + return false; + } + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isValidNumber(String context, String input, long minValue, long maxValue, boolean allowNull, ValidationErrorList errors) throws IntrusionException { + try { + getValidNumber(context, input, minValue, maxValue, allowNull); + return true; + } catch( ValidationException e ) { + errors.addError(context, e); + return false; + } + } + + /** + * {@inheritDoc} + */ + @Override + public Double getValidNumber(String context, String input, long minValue, long maxValue, boolean allowNull) throws ValidationException, IntrusionException { + Double minDoubleValue = new Double(minValue); + Double maxDoubleValue = new Double(maxValue); + return getValidDouble(context, input, minDoubleValue.doubleValue(), maxDoubleValue.doubleValue(), allowNull); + } + + /** + * {@inheritDoc} + */ + @Override + public Double getValidNumber(String context, String input, long minValue, long maxValue, boolean allowNull, ValidationErrorList errors) throws IntrusionException { + try { + return getValidNumber(context, input, minValue, maxValue, allowNull); + } catch (ValidationException e) { + errors.addError(context, e); + } + + return null; + } + + /** + * {@inheritDoc} + *

+ * This implementation does not throw {@link IntrusionException}. + */ + @Override + public boolean isValidDouble(String context, String input, double minValue, double maxValue, boolean allowNull) { + try { + getValidDouble( context, input, minValue, maxValue, allowNull ); + return true; + } catch( Exception e ) { + return false; + } + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isValidDouble(String context, String input, double minValue, double maxValue, boolean allowNull, ValidationErrorList errors) throws IntrusionException { + try { + getValidDouble( context, input, minValue, maxValue, allowNull ); + return true; + } catch( ValidationException e ) { + errors.addError(context, e); + return false; + } + } + + /** + * {@inheritDoc} + */ + @Override + public Double getValidDouble(String context, String input, double minValue, double maxValue, boolean allowNull) throws ValidationException, IntrusionException { + NumberValidationRule nvr = new NumberValidationRule( "number", encoder, minValue, maxValue ); + nvr.setAllowNull(allowNull); + return nvr.getValid(context, input); + } + + /** + * {@inheritDoc} + */ + @Override + public Double getValidDouble(String context, String input, double minValue, double maxValue, boolean allowNull, ValidationErrorList errors) throws IntrusionException { + try { + return getValidDouble(context, input, minValue, maxValue, allowNull); + } catch (ValidationException e) { + errors.addError(context, e); + } + + return new Double(Double.NaN); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isValidInteger(String context, String input, int minValue, int maxValue, boolean allowNull) throws IntrusionException { + try { + getValidInteger( context, input, minValue, maxValue, allowNull); + return true; + } catch( ValidationException e ) { + return false; + } + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isValidInteger(String context, String input, int minValue, int maxValue, boolean allowNull, ValidationErrorList errors) throws IntrusionException { + try { + getValidInteger( context, input, minValue, maxValue, allowNull); + return true; + } catch( ValidationException e ) { + errors.addError(context, e); + return false; + } + } + + /** + * {@inheritDoc} + */ + @Override + public Integer getValidInteger(String context, String input, int minValue, int maxValue, boolean allowNull) throws ValidationException, IntrusionException { + IntegerValidationRule ivr = new IntegerValidationRule( "number", encoder, minValue, maxValue ); + ivr.setAllowNull(allowNull); + return ivr.getValid(context, input); + } + + /** + * {@inheritDoc} + */ + @Override + public Integer getValidInteger(String context, String input, int minValue, int maxValue, boolean allowNull, ValidationErrorList errors) throws IntrusionException { + try { + return getValidInteger(context, input, minValue, maxValue, allowNull); + } catch (ValidationException e) { + errors.addError(context, e); + } + // error has been added to list, so return original input + return null; + } + + /** + * {@inheritDoc} + *

+ * This implementation does not throw {@link IntrusionException}. + */ + @Override + public boolean isValidFileContent(String context, byte[] input, int maxBytes, boolean allowNull) { + try { + getValidFileContent( context, input, maxBytes, allowNull); + return true; + } catch( Exception e ) { + return false; + } + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isValidFileContent(String context, byte[] input, int maxBytes, boolean allowNull, ValidationErrorList errors) throws IntrusionException { + try { + getValidFileContent( context, input, maxBytes, allowNull); + return true; + } catch( ValidationException e ) { + errors.addError(context, e); + return false; + } + } + + /** + * {@inheritDoc} + */ + @Override + public byte[] getValidFileContent(String context, byte[] input, int maxBytes, boolean allowNull) throws ValidationException, IntrusionException { + if (isEmpty(input)) { + if (allowNull) { + return null; + } + throw new ValidationException( context + ": Input required", "Input required: context=" + context + ", input=" + Arrays.toString(input), context ); + } + + long esapiMaxBytes = ESAPI.securityConfiguration().getAllowedFileUploadSize(); + if (input.length > esapiMaxBytes ) throw new ValidationException( context + ": Invalid file content can not exceed " + esapiMaxBytes + " bytes", "Exceeded ESAPI max length", context ); + if (input.length > maxBytes ) throw new ValidationException( context + ": Invalid file content can not exceed " + maxBytes + " bytes", "Exceeded maxBytes ( " + input.length + ")", context ); + + return input; + } + + /** + * {@inheritDoc} + */ + @Override + public byte[] getValidFileContent(String context, byte[] input, int maxBytes, boolean allowNull, ValidationErrorList errors) throws IntrusionException { + try { + return getValidFileContent(context, input, maxBytes, allowNull); + } catch (ValidationException e) { + errors.addError(context, e); + } + // return empty byte array on error + return new byte[0]; + } + + /** + * {@inheritDoc} + * + *

Note: On platforms that support symlinks, this function will fail canonicalization if directorypath + * is a symlink. For example, on MacOS X, /etc is actually /private/etc. If you mean to use /etc, use its real + * path (/private/etc), not the symlink (/etc).

+ */ + @Override + public boolean isValidFileUpload(String context, String directorypath, String filename, File parent, byte[] content, int maxBytes, boolean allowNull) throws IntrusionException { + return( isValidFileName( context, filename, allowNull ) && + isValidDirectoryPath( context, directorypath, parent, allowNull ) && + isValidFileContent( context, content, maxBytes, allowNull ) ); + } + + /** + * {@inheritDoc} + * + *

Note: On platforms that support symlinks, this function will fail canonicalization if directorypath + * is a symlink. For example, on MacOS X, /etc is actually /private/etc. If you mean to use /etc, use its real + * path (/private/etc), not the symlink (/etc).

+ */ + @Override + public boolean isValidFileUpload(String context, String directorypath, String filename, File parent, byte[] content, int maxBytes, boolean allowNull, ValidationErrorList errors) throws IntrusionException { + return( isValidFileName( context, filename, allowNull, errors ) && + isValidDirectoryPath( context, directorypath, parent, allowNull, errors ) && + isValidFileContent( context, content, maxBytes, allowNull, errors ) ); + } + + /** + * {@inheritDoc} + */ + @Override + public void assertValidFileUpload(String context, String directorypath, String filename, File parent, byte[] content, int maxBytes, List allowedExtensions, boolean allowNull) throws ValidationException, IntrusionException { + getValidFileName( context, filename, allowedExtensions, allowNull ); + getValidDirectoryPath( context, directorypath, parent, allowNull ); + getValidFileContent( context, content, maxBytes, allowNull ); + } + + /** + * {@inheritDoc} + */ + @Override + public void assertValidFileUpload(String context, String filepath, String filename, File parent, byte[] content, int maxBytes, List allowedExtensions, boolean allowNull, ValidationErrorList errors) + throws IntrusionException { + try { + assertValidFileUpload(context, filepath, filename, parent, content, maxBytes, allowedExtensions, allowNull); + } catch (ValidationException e) { + errors.addError(context, e); + } + } + + /** + * {@inheritDoc} + *

+ * This implementation does not throw {@link IntrusionException}. + */ + @Override + public boolean isValidListItem(String context, String input, List list) { + try { + getValidListItem( context, input, list); + return true; + } catch( Exception e ) { + return false; + } + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isValidListItem(String context, String input, List list, ValidationErrorList errors) { + try { + getValidListItem( context, input, list); + return true; + } catch( ValidationException e ) { + errors.addError(context, e); + return false; + } + } + + /** + * {@inheritDoc} + */ + @Override + public String getValidListItem(String context, String input, List list) throws ValidationException, IntrusionException { + if (list.contains(input)) return input; + throw new ValidationException( context + ": Invalid list item", "Invalid list item: context=" + context + ", input=" + input, context ); + } + + /** + * {@inheritDoc} + */ + @Override + public String getValidListItem(String context, String input, List list, ValidationErrorList errors) throws IntrusionException { + try { + return getValidListItem(context, input, list); + } catch (ValidationException e) { + errors.addError(context, e); + } + // error has been added to list, so return original input + return input; + } + + /** + * {@inheritDoc} + *

+ * This implementation does not throw {@link IntrusionException}. + */ + @Override + public boolean isValidHTTPRequestParameterSet(String context, HttpServletRequest request, Set requiredNames, Set optionalNames) { + try { + assertValidHTTPRequestParameterSet( context, request, requiredNames, optionalNames); + return true; + } catch( Exception e ) { + return false; + } + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isValidHTTPRequestParameterSet(String context, HttpServletRequest request, Set requiredNames, Set optionalNames, ValidationErrorList errors) { + try { + assertValidHTTPRequestParameterSet( context, request, requiredNames, optionalNames); + return true; + } catch( ValidationException e ) { + errors.addError(context, e); + return false; + } + } + + /** + * {@inheritDoc} + */ + @Override + public void assertValidHTTPRequestParameterSet(String context, HttpServletRequest request, Set required, Set optional) throws ValidationException, IntrusionException { + Set actualNames = request.getParameterMap().keySet(); + + // verify ALL required parameters are present + Set missing = new HashSet(required); + missing.removeAll(actualNames); + if (missing.size() > 0) { + throw new ValidationException( context + ": Invalid HTTP request missing parameters", "Invalid HTTP request missing parameters " + missing + ": context=" + context, context ); + } + + // verify ONLY optional + required parameters are present + Set extra = new HashSet(actualNames); + extra.removeAll(required); + extra.removeAll(optional); + if (extra.size() > 0) { + throw new ValidationException( context + ": Invalid HTTP request extra parameters " + extra, "Invalid HTTP request extra parameters " + extra + ": context=" + context, context ); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void assertValidHTTPRequestParameterSet(String context, HttpServletRequest request, Set required, Set optional, ValidationErrorList errors) throws IntrusionException { + try { + assertValidHTTPRequestParameterSet(context, request, required, optional); + } catch (ValidationException e) { + errors.addError(context, e); + } + } + + /** + * {@inheritDoc} + *

+ * Checks that all bytes are valid ASCII characters (between 33 and 126 inclusive). + * This implementation does no decoding. + *

+ * This implementation does not throw {@link IntrusionException}. + * + * @see Wikipedia - ASCII + */ + @Override + public boolean isValidPrintable(String context, char[] input, int maxLength, boolean allowNull) { + try { + getValidPrintable( context, input, maxLength, allowNull); + return true; + } catch( Exception e ) { + return false; + } + } + + /** + * {@inheritDoc} + *

+ * Checks that all bytes are valid ASCII characters (between 33 and 126 + * inclusive). This implementation does no decoding. + * + * @see Wikipedia - ASCII + */ + @Override + public boolean isValidPrintable(String context, char[] input, int maxLength, boolean allowNull, ValidationErrorList errors) throws IntrusionException { + try { + getValidPrintable( context, input, maxLength, allowNull); + return true; + } catch( ValidationException e ) { + errors.addError(context, e); + return false; + } + } + + /** + * {@inheritDoc} + *

+ * Input is valid if it only contains printable ASCII characters (33-126 inclusive). + * + * @see Wikipedia - ASCII + */ + @Override + public char[] getValidPrintable(String context, char[] input, int maxLength, boolean allowNull) throws ValidationException, IntrusionException { + if (isEmpty(input)) { + if (allowNull) { + return null; + } + throw new ValidationException(context + ": Input bytes required", "Input bytes required: HTTP request is null", context ); + } + + if (input.length > maxLength) { + throw new ValidationException(context + ": Input bytes can not exceed " + maxLength + " bytes", "Input exceeds maximum allowed length of " + maxLength + " by " + (input.length-maxLength) + " bytes: context=" + context + ", input=" + new String( input ), context); + } + + for (int i = 0; i < input.length; i++) { + if (input[i] <= 0x20 || input[i] >= 0x7E ) { + throw new ValidationException(context + ": Invalid input bytes: context=" + context, "Invalid non-ASCII input bytes, context=" + context + ", input=" + new String( input ), context); + } + } + return input; + } + + /** + * {@inheritDoc} + *

+ * Input is valid if it only contains printable ASCII characters (33-126 inclusive). + * + * @see Wikipedia - ASCII + */ + @Override + public char[] getValidPrintable(String context, char[] input, int maxLength, boolean allowNull, ValidationErrorList errors) + throws IntrusionException { + + try { + return getValidPrintable(context, input, maxLength, allowNull); + } catch (ValidationException e) { + errors.addError(context, e); + } + // error has been added to list, so return original input + return input; + } + + + /** + * {@inheritDoc} + *

+ * Returns true if input is valid printable ASCII characters (33-126 inclusive). + *

+ * This implementation does not throw {@link IntrusionException}. + * + * @see Wikipedia - ASCII + */ + @Override + public boolean isValidPrintable(String context, String input, int maxLength, boolean allowNull) { + try { + getValidPrintable( context, input, maxLength, allowNull); + return true; + } catch( Exception e ) { + return false; + } + } + + /** + * {@inheritDoc} + * + * Returns true if input is valid printable ASCII characters (33-126 inclusive). + * + * @see Wikipedia - ASCII + */ + @Override + public boolean isValidPrintable(String context, String input, int maxLength, boolean allowNull, ValidationErrorList errors) throws IntrusionException { + try { + getValidPrintable( context, input, maxLength, allowNull); + return true; + } catch( ValidationException e ) { + errors.addError(context, e); + return false; + } + } + + /** + * {@inheritDoc} + *

+ * Input is valid if it only contains printable ASCII characters (33-126 inclusive). + * + * @see Wikipedia - ASCII + */ + @Override + public String getValidPrintable(String context, String input, int maxLength, boolean allowNull) throws ValidationException { + try { + String canonical = encoder.canonicalize(input); + return new String( getValidPrintable( context, canonical.toCharArray(), maxLength, allowNull) ); + //TODO - changed this to base Exception since we no longer need EncodingException + //TODO - this is a bit lame: we need to re-think this function. + } catch (Exception e) { + throw new ValidationException( context + ": Invalid printable input", "Invalid encoding of printable input, context=" + context + ", input=" + input, e, context); + } + } + + /** + * {@inheritDoc} + * + * Input is valid if it only contains printable ASCII characters (33-126 inclusive). + * + * @see Wikipedia - ASCII + */ + @Override + public String getValidPrintable(String context, String input, int maxLength, boolean allowNull, ValidationErrorList errors) throws IntrusionException { + try { + return getValidPrintable(context, input, maxLength, allowNull); + } catch (ValidationException e) { + errors.addError(context, e); + } + // error has been added to list, so return original input + return input; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isValidRedirectLocation(String context, String input, boolean allowNull) throws IntrusionException { + SecurityConfiguration sc = ESAPI.securityConfiguration(); + return ESAPI.validator().isValidInput( context, input, "Redirect", sc.getIntProp("HttpUtilities.maxRedirectLength"), allowNull); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isValidRedirectLocation(String context, String input, boolean allowNull, ValidationErrorList errors) throws IntrusionException { + SecurityConfiguration sc = ESAPI.securityConfiguration(); + return ESAPI.validator().isValidInput( context, input, "Redirect", sc.getIntProp("HttpUtilities.maxRedirectLength"), allowNull, errors); + } + + /** + * {@inheritDoc} + */ + @Override + public String getValidRedirectLocation(String context, String input, boolean allowNull) throws ValidationException, IntrusionException { + SecurityConfiguration sc = ESAPI.securityConfiguration(); + return ESAPI.validator().getValidInput( context, input, "Redirect", sc.getIntProp("HttpUtilities.maxRedirectLength"), allowNull); + } + + /** + * {@inheritDoc} + */ + @Override + public String getValidRedirectLocation(String context, String input, boolean allowNull, ValidationErrorList errors) throws IntrusionException { + try { + return getValidRedirectLocation(context, input, allowNull); + } catch (ValidationException e) { + errors.addError(context, e); + } + // error has been added to list, so return original input + return input; + } + + /** + * {@inheritDoc} + *

+ * This implementation reads until a newline or the specified number of + * characters. + */ + @Override + public String safeReadLine(InputStream in, int max) throws ValidationException { + if (max <= 0) { + throw new ValidationAvailabilityException( "Invalid input", "Invalid readline. Must read a positive number of bytes from the stream"); + } + + StringBuilder sb = new StringBuilder(); + int count = 0; + int c; + + try { + while (true) { + c = in.read(); + if ( c == -1 ) { + if (sb.length() == 0) { + return null; + } + break; + } + if (c == '\n' || c == '\r') { + break; + } + count++; + if (count > max) { + throw new ValidationAvailabilityException( "Invalid input", "Invalid readLine. Read more than maximum characters allowed (" + max + ")"); + } + sb.append((char) c); + } + return sb.toString(); + } catch (IOException e) { + throw new ValidationAvailabilityException( "Invalid input", "Invalid readLine. Problem reading from input stream", e); + } + } + + /** + * Helper function to check if a String is empty + * + * @param input string input value + * @return boolean response if input is empty or not + */ + private final boolean isEmpty(String input) { + return (input==null || input.trim().length() == 0); + } + + /** + * Helper function to check if a byte array is empty + * + * @param input string input value + * @return boolean response if input is empty or not + */ + private final boolean isEmpty(byte[] input) { + return (input==null || input.length == 0); + } + + + /** + * Helper function to check if a char array is empty + * + * @param input string input value + * @return boolean response if input is empty or not + */ + private final boolean isEmpty(char[] input) { + return (input==null || input.length == 0); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isValidURI(String context, String input, boolean allowNull) { + boolean isValid = false; + boolean inputIsNullOrEmpty = input == null || "".equals(input); + Encoder encoder = ESAPI.encoder(); + try{ + URI compliantURI = null == input ? new URI("") : this.getRfcCompliantURI(input); + if(null != compliantURI && input != null){ + String canonicalizedURI = encoder.getCanonicalizedURI(compliantURI); + //if getCanonicalizedURI doesn't throw an IntrusionException, then the URI contains no mixed or + //double-encoding attacks. + logger.debug(Logger.SECURITY_SUCCESS, "We did not detect any mixed or multiple encoding in the uri:[" + input + "]"); + Validator v = ESAPI.validator(); + //This part will use the regex from validation.properties. This regex should be super-simple, and + //used mainly to restrict certain parts of a URL. + Pattern p = ESAPI.securityConfiguration().getValidationPattern( "URL" ); + if(p != null){ + //We're doing this instead of using the normal validator API, because it will canonicalize the input again + //and if the URI has any queries that also happen to match HTML entities, like ¶ + //it will cease conforming to the regex we now specify for a URL. + isValid = p.matcher(canonicalizedURI).matches(); + }else{ + logger.error(Logger.EVENT_FAILURE, "Invalid regex pulled from configuration. Check the regex for URL and correct."); + } + }else{ + if(allowNull && inputIsNullOrEmpty ){ + isValid = true; + } + } + + }catch (IntrusionException e){ + logger.error(Logger.SECURITY_FAILURE, e.getMessage()); + isValid = false; + } catch (URISyntaxException e) { + logger.error(Logger.EVENT_FAILURE, e.getMessage()); + } + + + return isValid; + } + + /** + * {@inheritDoc} + */ + @Override + public URI getRfcCompliantURI(String input){ + URI rval = null; + try { + rval = new URI(input); + } catch (URISyntaxException e) { + logger.error(Logger.EVENT_FAILURE, e.getMessage()); + } + return rval; + } +} diff --git a/src/main/java/org/owasp/esapi/reference/FileBasedAuthenticator.java b/src/main/java/org/owasp/esapi/reference/FileBasedAuthenticator.java new file mode 100644 index 000000000..111e3f8be --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/FileBasedAuthenticator.java @@ -0,0 +1,754 @@ +/** + * 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.reference; + +import org.owasp.esapi.*; +import org.owasp.esapi.errors.*; + +import java.io.*; +import java.util.*; + +/** + * Reference implementation of the Authenticator interface. This reference implementation is intended to be + * an EXAMPLE only and is not really suitable for enterprise-wide applications. It is backed by a simple unsorted + * text file that contains serialized information about users and it uses a relative weak password hashing algorithm. + * (For further details, see the "See Also" section, below.) + *

+ * Many organizations will want to create their own implementation of the methods provided in the + * {@code Authenticator} interface backed by their own user repository as this reference implementation + * is not very scalable. 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
+ * 
+ *

+ * + * @author Jeff Williams at Aspect Security + * @author Chris Schmidt (chrisisbeef .at. gmail.com) Digital Ritual Software + * @see org.owasp.esapi.Authenticator + * @see #hashPassword(String password, String accountName) + * @see GitHub Issue #233: Weak password storage + * @since June 1, 2007 + */ +public class FileBasedAuthenticator extends AbstractAuthenticator { + + private static volatile Authenticator singletonInstance; + + public static Authenticator getInstance() + { + if ( singletonInstance == null ) { + synchronized ( FileBasedAuthenticator.class ) { + if ( singletonInstance == null ) { + singletonInstance = new FileBasedAuthenticator(); + } + } + } + return singletonInstance; + } + + /** + * The logger. + */ + private final Logger logger = ESAPI.getLogger("Authenticator"); + + /** + * The file that contains the user db + */ + private File userDB = null; + + /** + * How frequently to check the user db for external modifications + */ + private long checkInterval = 60 * 1000; + + /** + * The last modified time we saw on the user db. + */ + private long lastModified = 0; + + /** + * The last time we checked if the user db had been modified externally + */ + private long lastChecked = 0; + + private static final int MAX_ACCOUNT_NAME_LENGTH = 250; + + /** + * 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: + *

+     * 

+ * java -Dorg.owasp.esapi.resources="/path/resources" -classpath esapi.jar org.owasp.esapi.Authenticator alice password admin + *

+ *

+ * + * @param args the arguments (username, password, role) + * @throws Exception the exception + */ + public static void main(String[] args) throws Exception { + if (args.length != 3) { + System.out.println("Usage: Authenticator accountname password role"); + return; + } + FileBasedAuthenticator auth = new FileBasedAuthenticator(); + String accountName = args[0].toLowerCase(); + String password = args[1]; + String role = args[2]; + DefaultUser user = (DefaultUser) auth.getUser(args[0]); + if (user == null) { + user = new DefaultUser(accountName); + String newHash = auth.hashPassword(password, accountName); + auth.setHashedPassword(user, newHash); + user.addRole(role); + user.enable(); + user.unlock(); + auth.userMap.put(user.getAccountId(), user); + System.out.println("New user created: " + accountName); + auth.saveUsers(); + System.out.println("User account " + user.getAccountName() + " updated"); + } else { + System.err.println("User account " + user.getAccountName() + " already exists!"); + } + } + + /** + * Add a hash to a User's hashed password list. This method is used to store a user's old password hashes + * to be sure that any new passwords are not too similar to old passwords. + * + * @param user the user to associate with the new hash + * @param hash the hash to store in the user's password hash list + */ + private void setHashedPassword(User user, String hash) { + List hashes = getAllHashedPasswords(user, true); + hashes.add(0, hash); + if (hashes.size() > ESAPI.securityConfiguration().getMaxOldPasswordHashes()) { + hashes.remove(hashes.size() - 1); + } + logger.info(Logger.SECURITY_SUCCESS, "New hashed password stored for " + user.getAccountName()); + } + + /** + * Return the specified User's current hashed password. + * + * @param user this User's current hashed password will be returned + * @return the specified User's current hashed password + */ + String getHashedPassword(User user) { + List hashes = getAllHashedPasswords(user, false); + return (String) hashes.get(0); + } + + /** + * Set the specified User's old password hashes. This will not set the User's current password hash. + * + * @param user the User whose old password hashes will be set + * @param oldHashes a list of the User's old password hashes + */ + void setOldPasswordHashes(User user, List oldHashes) { + List hashes = getAllHashedPasswords(user, true); + if (hashes.size() > 1) { + hashes.removeAll(hashes.subList(1, hashes.size())); + } + hashes.addAll(oldHashes); + } + + /** + * Returns all of the specified User's hashed passwords. If the User's list of passwords is null, + * and create is set to true, an empty password list will be associated with the specified User + * and then returned. If the User's password map is null and create is set to false, an exception + * will be thrown. + * + * @param user the User whose old hashes should be returned + * @param create true - if no password list is associated with this user, create one + * false - if no password list is associated with this user, do not create one + * @return a List containing all of the specified User's password hashes + */ + List getAllHashedPasswords(User user, boolean create) { + List hashes = passwordMap.get(user); + if (hashes != null) { + return hashes; + } + if (create) { + hashes = new ArrayList(); + passwordMap.put(user, hashes); + return hashes; + } + throw new RuntimeException("No hashes found for " + user.getAccountName() + ". Is User.hashcode() and equals() implemented correctly?"); + } + + /** + * Get a List of the specified User's old password hashes. This will not return the User's current + * password hash. + * + * @param user he user whose old password hashes should be returned + * @return the specified User's old password hashes + */ + List getOldPasswordHashes(User user) { + List hashes = getAllHashedPasswords(user, false); + if (hashes.size() > 1) { + return Collections.unmodifiableList(hashes.subList(1, hashes.size())); + } + return Collections.emptyList(); + } + + /** + * The user map. + */ + private Map userMap = new HashMap(); + + // Map>, where the strings are password hashes, with the current hash in entry 0 + private Map> passwordMap = new Hashtable>(); + + + + /** + * + */ + private FileBasedAuthenticator() { + super(); + } + + + /** + * {@inheritDoc} + */ + public synchronized User createUser(String accountName, String password1, String password2) throws AuthenticationException { + loadUsersIfNecessary(); + if (accountName == null) { + throw new AuthenticationAccountsException("Account creation failed", "Attempt to create user with null accountName"); + } + if (getUser(accountName) != null) { + throw new AuthenticationAccountsException("Account creation failed", "Duplicate user creation denied for " + accountName); + } + + verifyAccountNameStrength(accountName); + + if (password1 == null) { + throw new AuthenticationCredentialsException("Invalid account name", "Attempt to create account " + accountName + " with a null password"); + } + + DefaultUser user = new DefaultUser(accountName); + + verifyPasswordStrength(null, password1, user); + + if (!password1.equals(password2)) { + throw new AuthenticationCredentialsException("Passwords do not match", "Passwords for " + accountName + " do not match"); + } + + try { + setHashedPassword(user, hashPassword(password1, accountName)); + } catch (EncryptionException ee) { + throw new AuthenticationException("Internal error", "Error hashing password for " + accountName, ee); + } + userMap.put(user.getAccountId(), user); + logger.info(Logger.SECURITY_SUCCESS, "New user created: " + accountName); + saveUsers(); + return user; + } + + /** + * {@inheritDoc} + */ + public String generateStrongPassword() { + return generateStrongPassword(""); + } + + /** + * Generate a strong password that is not similar to the specified old password. + * + * @param oldPassword the password to be compared to the new password for similarity + * @return a new strong password that is dissimilar to the specified old password + */ + private String generateStrongPassword(String oldPassword) { + Randomizer r = ESAPI.randomizer(); + int letters = r.getRandomInteger(4, 6); // inclusive, exclusive + int digits = 7 - letters; + String passLetters = r.getRandomString(letters, EncoderConstants.CHAR_PASSWORD_LETTERS); + String passDigits = r.getRandomString(digits, EncoderConstants.CHAR_PASSWORD_DIGITS); + String passSpecial = r.getRandomString(1, EncoderConstants.CHAR_PASSWORD_SPECIALS); + String newPassword = passLetters + passSpecial + passDigits; + if (StringUtilities.getLevenshteinDistance(oldPassword, newPassword) > 5) { + return newPassword; + } + return generateStrongPassword(oldPassword); + } + + /** + * {@inheritDoc} + */ + public void changePassword(User user, String currentPassword, + String newPassword, String newPassword2) + throws AuthenticationException { + String accountName = user.getAccountName(); + try { + String currentHash = getHashedPassword(user); + String verifyHash = hashPassword(currentPassword, accountName); + if (!currentHash.equals(verifyHash)) { + throw new AuthenticationCredentialsException("Password change failed", "Authentication failed for password change on user: " + accountName); + } + if (newPassword == null || newPassword2 == null || !newPassword.equals(newPassword2)) { + throw new AuthenticationCredentialsException("Password change failed", "Passwords do not match for password change on user: " + accountName); + } + verifyPasswordStrength(currentPassword, newPassword, user); + user.setLastPasswordChangeTime(new Date()); + String newHash = hashPassword(newPassword, accountName); + if (getOldPasswordHashes(user).contains(newHash)) { + throw new AuthenticationCredentialsException("Password change failed", "Password change matches a recent password for user: " + accountName); + } + setHashedPassword(user, newHash); + logger.info(Logger.SECURITY_SUCCESS, "Password changed for user: " + accountName); + // jtm - 11/2/2010 - added to resolve http://code.google.com/p/owasp-esapi-java/issues/detail?id=13 + saveUsers(); + } catch (EncryptionException ee) { + throw new AuthenticationException("Password change failed", "Encryption exception changing password for " + accountName, ee); + } + } + + /** + * {@inheritDoc} + */ + public boolean verifyPassword(User user, String password) { + String accountName = user.getAccountName(); + try { + String hash = hashPassword(password, accountName); + String currentHash = getHashedPassword(user); + if (hash.equals(currentHash)) { + user.setLastLoginTime(new Date()); + ((DefaultUser) user).setFailedLoginCount(0); + logger.info(Logger.SECURITY_SUCCESS, "Password verified for " + accountName); + return true; + } + } catch (EncryptionException e) { + logger.fatal(Logger.SECURITY_FAILURE, "Encryption error verifying password for " + accountName); + } + logger.fatal(Logger.SECURITY_FAILURE, "Password verification failed for " + accountName); + return false; + } + + /** + * {@inheritDoc} + */ + public String generateStrongPassword(User user, String oldPassword) { + String newPassword = generateStrongPassword(oldPassword); + if (newPassword != null) { + logger.info(Logger.SECURITY_SUCCESS, "Generated strong password for " + user.getAccountName()); + } + return newPassword; + } + + /** + * {@inheritDoc} + */ + public synchronized User getUser(long accountId) { + if (accountId == 0) { + return User.ANONYMOUS; + } + loadUsersIfNecessary(); + return userMap.get(accountId); + } + + /** + * {@inheritDoc} + */ + public synchronized User getUser(String accountName) { + if (accountName == null) { + return User.ANONYMOUS; + } + loadUsersIfNecessary(); + for (User u : userMap.values()) { + if (u.getAccountName().equalsIgnoreCase(accountName)) { + return u; + } + } + return null; + } + + + + /** + * {@inheritDoc} + */ + public synchronized Set getUserNames() { + loadUsersIfNecessary(); + HashSet results = new HashSet(); + for (User u : userMap.values()) { + results.add(u.getAccountName()); + } + return results; + } + + /** + * {@inheritDoc} + * + * WARNING: There are several weaknesses in this method: + *
    + *
  1. The salt should really be a randomly generated salt, typically at + * least 64-bits, but in this method, the {@code accountName} parameter is + * used as the salt.
  2. + *
  3. This salt is then combined with the ESAPI.properties file's + * {@code Encryptor.MasterSalt}, meaning that if that property is changed, + * all previously stored passwords become invalid and need to be reset.
  4. + *
  5. Only 1024 iterations of the hash algorithm (SHA-512) are made. While that + * may have been fine in 2007, it is no longer considered sufficient.
  6. + *
+ * + * @throws EncryptionException + */ + public String hashPassword(String password, String accountName) throws EncryptionException { + // Here is but one weakness: This salt should ideally be a _random_ salt, + // at least 64 bits in length. Unfortunately, if anyone is actually using + // this method in a production application (let's hope not) fixing this + // now will those application's previously stored passwords. See this + // GitHub issue comment for further details: + // https://github.com/ESAPI/esapi-java-legacy/issues/233#issuecomment-450401400 + String salt = accountName.toLowerCase(); + // + // Other weaknesses are that only 1024 iterations of the hash algorithm + // (SHA-512) is used and the final hash is tied to the Encryptor.MasterSalt + // so if that is ever changed, all users passwords must be reset. + return ESAPI.encryptor().hash(password, salt); + } + + /** + * Load users if they haven't been loaded in a while. + */ + protected void loadUsersIfNecessary() { + if (userDB == null) { + userDB = ESAPI.securityConfiguration().getResourceFile("users.txt"); + } + if (userDB == null) { + userDB = new File(System.getProperty("user.home") + "/.esapi", "users.txt"); + try { + if (!userDB.createNewFile()) throw new IOException("Unable to create the user file"); + logger.warning(Logger.SECURITY_SUCCESS, "Created " + userDB.getAbsolutePath()); + } catch (IOException e) { + logger.fatal(Logger.SECURITY_FAILURE, "Could not create " + userDB.getAbsolutePath(), e); + } + } + + // We only check at most every checkInterval milliseconds + long now = System.currentTimeMillis(); + if (now - lastChecked < checkInterval) { + return; + } + lastChecked = now; + + if (lastModified == userDB.lastModified()) { + return; + } + loadUsersImmediately(); + } + + // file was touched so reload it + /** + * + */ + protected void loadUsersImmediately() { + synchronized (this) { + logger.trace(Logger.SECURITY_SUCCESS, "Loading users from " + userDB.getAbsolutePath(), null); + + BufferedReader reader = null; + try { + HashMap map = new HashMap(); + reader = new BufferedReader(new FileReader(userDB)); + String line; + while ((line = reader.readLine()) != null) { + if (line.length() > 0 && line.charAt(0) != '#') { + DefaultUser user = createUser(line); + if (map.containsKey(new Long(user.getAccountId()))) { + logger.fatal(Logger.SECURITY_FAILURE, "Problem in user file. Skipping duplicate user: " + user, null); + } + map.put(user.getAccountId(), user); + } + } + userMap = map; + this.lastModified = System.currentTimeMillis(); + logger.trace(Logger.SECURITY_SUCCESS, "User file reloaded: " + map.size(), null); + } catch (Exception e) { + logger.fatal(Logger.SECURITY_FAILURE, "Failure loading user file: " + userDB.getAbsolutePath(), e); + } finally { + try { + if (reader != null) { + reader.close(); + } + } catch (IOException e) { + logger.fatal(Logger.SECURITY_FAILURE, "Failure closing user file: " + userDB.getAbsolutePath(), e); + } + } + } + } + + /** + * Create a new user with all attributes from a String. The format is: + * accountId | accountName | password | roles (comma separated) | unlocked | enabled | old password hashes (comma separated) | last host address | last password change time | last long time | last failed login time | expiration time | failed login count + * This method verifies the account name and password strength, creates a new CSRF token, then returns the newly created user. + * + * @param line parameters to set as attributes for the new User. + * @return the newly created User + * @throws AuthenticationException + */ + private DefaultUser createUser(String line) throws AuthenticationException { + String[] parts = line.split(" *\\| *"); + String accountIdString = parts[0]; + long accountId = Long.parseLong(accountIdString); + String accountName = parts[1]; + + verifyAccountNameStrength(accountName); + DefaultUser user = new DefaultUser(accountName); + user.accountId = accountId; + + String password = parts[2]; + verifyPasswordStrength(null, password, user); + setHashedPassword(user, password); + + String[] roles = parts[3].toLowerCase().split(" *, *"); + for (String role : roles) { + if (!"".equals(role)) { + user.addRole(role); + } + } + if (!"unlocked".equalsIgnoreCase(parts[4])) { + user.lock(); + } + if ("enabled".equalsIgnoreCase(parts[5])) { + user.enable(); + } else { + user.disable(); + } + + // generate a new csrf token + user.resetCSRFToken(); + + setOldPasswordHashes(user, Arrays.asList(parts[6].split(" *, *"))); + user.setLastHostAddress("null".equals(parts[7]) ? null : parts[7]); + user.setLastPasswordChangeTime(new Date(Long.parseLong(parts[8]))); + user.setLastLoginTime(new Date(Long.parseLong(parts[9]))); + user.setLastFailedLoginTime(new Date(Long.parseLong(parts[10]))); + user.setExpirationTime(new Date(Long.parseLong(parts[11]))); + user.setFailedLoginCount(Integer.parseInt(parts[12])); + return user; + } + + /** + * {@inheritDoc} + */ + public synchronized void removeUser(String accountName) throws AuthenticationException { + loadUsersIfNecessary(); + User user = getUser(accountName); + if (user == null) { + throw new AuthenticationAccountsException("Remove user failed", "Can't remove invalid accountName " + accountName); + } + userMap.remove(user.getAccountId()); + logger.info(Logger.SECURITY_SUCCESS, "Removing user " + user.getAccountName()); + passwordMap.remove(user); + saveUsers(); + } + + /** + * Saves the user database to the file system. In this implementation you must call save to commit any changes to + * the user file. Otherwise changes will be lost when the program ends. + * + * @throws AuthenticationException if the user file could not be written + */ + public synchronized void saveUsers() throws AuthenticationException { + PrintWriter writer = null; + try { + writer = new PrintWriter(new FileWriter(userDB)); + writer.println("# This is the user file associated with the ESAPI library from http://www.owasp.org"); + writer.println("# accountId | accountName | hashedPassword | roles | locked | enabled | csrfToken | oldPasswordHashes | lastPasswordChangeTime | lastLoginTime | lastFailedLoginTime | expirationTime | failedLoginCount"); + writer.println(); + saveUsers(writer); + writer.flush(); + logger.info(Logger.SECURITY_SUCCESS, "User file written to disk"); + } catch (IOException e) { + logger.fatal(Logger.SECURITY_FAILURE, "Problem saving user file " + userDB.getAbsolutePath(), e); + throw new AuthenticationException("Internal Error", "Problem saving user file " + userDB.getAbsolutePath(), e); + } finally { + if (writer != null) { + writer.close(); + lastModified = userDB.lastModified(); + lastChecked = lastModified; + } + } + } + + /** + * Save users. + * + * @param writer the print writer to use for saving + */ + protected synchronized void saveUsers(PrintWriter writer) throws AuthenticationCredentialsException { + for (Object o : getUserNames()) { + String accountName = (String) o; + DefaultUser u = (DefaultUser) getUser(accountName); + if (u != null && !u.isAnonymous()) { + writer.println(save(u)); + } else { + throw new AuthenticationCredentialsException("Problem saving user", "Skipping save of user " + accountName); + } + } + } + + /** + * Save. + * + * @param user the User to save + * @return a line containing properly formatted information to save regarding the user + */ + private String save(DefaultUser user) { + StringBuilder sb = new StringBuilder(); + sb.append(user.getAccountId()); + sb.append(" | "); + sb.append(user.getAccountName()); + sb.append(" | "); + sb.append(getHashedPassword(user)); + sb.append(" | "); + sb.append(dump(user.getRoles())); + sb.append(" | "); + sb.append(user.isLocked() ? "locked" : "unlocked"); + sb.append(" | "); + sb.append(user.isEnabled() ? "enabled" : "disabled"); + sb.append(" | "); + sb.append(dump(getOldPasswordHashes(user))); + sb.append(" | "); + sb.append(user.getLastHostAddress()); + sb.append(" | "); + sb.append(user.getLastPasswordChangeTime().getTime()); + sb.append(" | "); + sb.append(user.getLastLoginTime().getTime()); + sb.append(" | "); + sb.append(user.getLastFailedLoginTime().getTime()); + sb.append(" | "); + sb.append(user.getExpirationTime().getTime()); + sb.append(" | "); + sb.append(user.getFailedLoginCount()); + return sb.toString(); + } + + /** + * Dump a collection as a comma-separated list. + * + * @param c the collection to convert to a comma separated list + * @return a comma separated list containing the values in c + */ + private String dump(Collection c) { + StringBuilder sb = new StringBuilder(); + for (String s : c) { + sb.append(s).append(","); + } + if ( c.size() > 0) { + return sb.toString().substring(0, sb.length() - 1); + } + return ""; + + } + + /** + * {@inheritDoc} + *

+ * This implementation simply verifies that account names are at least 5 characters long. This helps to defeat a + * brute force attack, however the real strength comes from the name length and complexity. + * + * @param newAccountName + */ + public void verifyAccountNameStrength(String newAccountName) throws AuthenticationException { + if (newAccountName == null) { + throw new AuthenticationCredentialsException("Invalid account name", "Attempt to create account with a null account name"); + } + if (!ESAPI.validator().isValidInput("verifyAccountNameStrength", newAccountName, "AccountName", MAX_ACCOUNT_NAME_LENGTH, false)) { + throw new AuthenticationCredentialsException("Invalid account name", "New account name is not valid: " + newAccountName); + } + } + + /** + * {@inheritDoc} + *

+ * This implementation checks: - for any 3 character substrings of the old password - for use of a length * + * character sets > 16 (where character sets are upper, lower, digit, and special + * jtm - 11/16/2010 - added check to verify pw != username (fix for http://code.google.com/p/owasp-esapi-java/issues/detail?id=108) + */ + public void verifyPasswordStrength(String oldPassword, String newPassword, User user) throws AuthenticationException { + if (newPassword == null) { + throw new AuthenticationCredentialsException("Invalid password", "New password cannot be null"); + } + + // can't change to a password that contains any 3 character substring of old password + if (oldPassword != null) { + int length = oldPassword.length(); + for (int i = 0; i < length - 2; i++) { + String sub = oldPassword.substring(i, i + 3); + if (newPassword.indexOf(sub) > -1) { + throw new AuthenticationCredentialsException("Invalid password", "New password cannot contain pieces of old password"); + } + } + } + + // new password must have enough character sets and length + int charsets = 0; + for (int i = 0; i < newPassword.length(); i++) { + if (Arrays.binarySearch(EncoderConstants.CHAR_LOWERS, newPassword.charAt(i)) >= 0) { + charsets++; + break; + } + } + for (int i = 0; i < newPassword.length(); i++) { + if (Arrays.binarySearch(EncoderConstants.CHAR_UPPERS, newPassword.charAt(i)) >= 0) { + charsets++; + break; + } + } + for (int i = 0; i < newPassword.length(); i++) { + if (Arrays.binarySearch(EncoderConstants.CHAR_DIGITS, newPassword.charAt(i)) >= 0) { + charsets++; + break; + } + } + for (int i = 0; i < newPassword.length(); i++) { + if (Arrays.binarySearch(EncoderConstants.CHAR_SPECIALS, newPassword.charAt(i)) >= 0) { + charsets++; + break; + } + } + + // calculate and verify password strength + int strength = newPassword.length() * charsets; + if (strength < 16) { + throw new AuthenticationCredentialsException("Invalid password", "New password is not long and complex enough"); + } + + String accountName = user.getAccountName(); + + //jtm - 11/3/2010 - fix for bug http://code.google.com/p/owasp-esapi-java/issues/detail?id=108 + if (accountName.equalsIgnoreCase(newPassword)) { + //password can't be account name + throw new AuthenticationCredentialsException("Invalid password", "Password matches account name, irrespective of case"); + } + } + +} diff --git a/src/main/java/org/owasp/esapi/reference/IntegerAccessReferenceMap.java b/src/main/java/org/owasp/esapi/reference/IntegerAccessReferenceMap.java new file mode 100644 index 000000000..24ff9d6e9 --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/IntegerAccessReferenceMap.java @@ -0,0 +1,80 @@ +/** + * 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.reference; + +import java.util.Set; + +/** + * Reference implementation of the AccessReferenceMap interface. This + * implementation generates integers for indirect references. + * + * @author Jeff Williams (jeff.williams@aspectsecurity.com) + * @author Chris Schmidt (chrisisbeef@gmail.com) + * @since June 1, 2007 + * @see org.owasp.esapi.AccessReferenceMap + */ +public class IntegerAccessReferenceMap extends AbstractAccessReferenceMap { + + private static final long serialVersionUID = 5311769278372489771L; + + int count = 1; + + /** + * TODO Javadoc + */ + public IntegerAccessReferenceMap() + { + } + + /** + * TODO Javadoc + */ + public IntegerAccessReferenceMap(int initialSize) + { + super(initialSize); + } + + /** + * TODO Javadoc + */ + public IntegerAccessReferenceMap(Set directReferences) + { + super(directReferences.size()); + update(directReferences); + } + + /** + * TODO Javadoc + */ + public IntegerAccessReferenceMap(Set directReferences, int initialSize) + { + super(initialSize); + update(directReferences); + } + + /** + * {@inheritDoc} + * Note: this is final as redefinition by subclasses + * can lead to use before initialization issues as + * {@link #IntegerAccessReferenceMap(Set)} and + * {@link #IntegerAccessReferenceMap(Set,int)} both call it + * internally. + */ + protected final synchronized String getUniqueReference() { + return "" + count++; // returns a string version of the counter + } + +} diff --git a/src/main/java/org/owasp/esapi/reference/RandomAccessReferenceMap.java b/src/main/java/org/owasp/esapi/reference/RandomAccessReferenceMap.java new file mode 100644 index 000000000..1018b64be --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/RandomAccessReferenceMap.java @@ -0,0 +1,85 @@ +/** + * 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.reference; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.EncoderConstants; + +import java.util.Set; + +/** + * 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. + * + * @author Jeff Williams (jeff.williams@aspectsecurity.com) + * @author Chris Schmidt (chrisisbeef@gmail.com) + * @see org.owasp.esapi.AccessReferenceMap + * @since June 1, 2007 + */ +public class RandomAccessReferenceMap extends AbstractAccessReferenceMap +{ + + private static final long serialVersionUID = 8544133840739803001L; + + public RandomAccessReferenceMap(int initialSize) + { + super(initialSize); + } + + /** + * This AccessReferenceMap implementation uses short random strings to + * create a layer of indirection. Other possible implementations would use + * simple integers as indirect references. + */ + public RandomAccessReferenceMap() + { + // call update to set up the references + } + + public RandomAccessReferenceMap(Set directReferences) + { + super(directReferences.size()); + update(directReferences); + } + + public RandomAccessReferenceMap(Set directReferences, int initialSize) + { + super(initialSize); + update(directReferences); + } + + /** + * {@inheritDoc} + * Note: this is final as redefinition by subclasses can lead to use + * before initialization issues as + * {@link #RandomAccessReferenceMap(Set)} and + * {@link #RandomAccessReferenceMap(Set,int)} both call it internally. + */ + protected final synchronized String getUniqueReference() + { + String candidate; + do + { + candidate = ESAPI.randomizer().getRandomString(6, EncoderConstants.CHAR_ALPHANUMERICS); + } + while (itod.keySet().contains(candidate)); + return candidate; + } +} diff --git a/src/main/java/org/owasp/esapi/reference/accesscontrol/AlwaysFalseACR.java b/src/main/java/org/owasp/esapi/reference/accesscontrol/AlwaysFalseACR.java new file mode 100644 index 000000000..bd25ab86f --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/accesscontrol/AlwaysFalseACR.java @@ -0,0 +1,9 @@ +package org.owasp.esapi.reference.accesscontrol; + +public class AlwaysFalseACR extends BaseACR { + +// @Override + public boolean isAuthorized(Object runtimeParameter) { + return false; + } +} diff --git a/src/main/java/org/owasp/esapi/reference/accesscontrol/AlwaysTrueACR.java b/src/main/java/org/owasp/esapi/reference/accesscontrol/AlwaysTrueACR.java new file mode 100644 index 000000000..a132722ba --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/accesscontrol/AlwaysTrueACR.java @@ -0,0 +1,9 @@ +package org.owasp.esapi.reference.accesscontrol; + +public class AlwaysTrueACR extends BaseACR { + +// @Override + public boolean isAuthorized(Object runtimeParameter) { + return true; + } +} diff --git a/src/main/java/org/owasp/esapi/reference/accesscontrol/BaseACR.java b/src/main/java/org/owasp/esapi/reference/accesscontrol/BaseACR.java new file mode 100644 index 000000000..1e307a731 --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/accesscontrol/BaseACR.java @@ -0,0 +1,18 @@ +package org.owasp.esapi.reference.accesscontrol; + +import org.owasp.esapi.AccessControlRule; + +abstract public class BaseACR implements AccessControlRule { + + protected P policyParameters; + +// @Override + public void setPolicyParameters(P policyParameter) { + this.policyParameters = policyParameter; + } + +// @Override + public P getPolicyParameters() { + return policyParameters; + } +} diff --git a/src/main/java/org/owasp/esapi/reference/accesscontrol/DelegatingACR.java b/src/main/java/org/owasp/esapi/reference/accesscontrol/DelegatingACR.java new file mode 100644 index 000000000..eaa35799c --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/accesscontrol/DelegatingACR.java @@ -0,0 +1,100 @@ +package org.owasp.esapi.reference.accesscontrol; + +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Iterator; +import java.util.Vector; +import java.util.Arrays; + +import org.apache.commons.collections4.iterators.ArrayListIterator; + +public class DelegatingACR extends BaseACR { + protected Method delegateMethod; + protected Object delegateInstance; + + @Override + public void setPolicyParameters(DynaBeanACRParameter policyParameter) { + String delegateClassName = policyParameter.getString("delegateClass", "").trim(); + String methodName = policyParameter.getString("delegateMethod", "").trim(); + String[] parameterClassNames = policyParameter.getStringArray("parameterClasses"); + + //Convert the classNames into Classes and get the delegate method. + Class delegateClass = getClass(delegateClassName, "delegate"); + Class parameterClasses[] = getParameters(parameterClassNames); + try { + this.delegateMethod = delegateClass.getMethod(methodName, parameterClasses); + } catch (SecurityException e) { + throw new IllegalArgumentException(e.getMessage() + + " delegateClass.delegateMethod(parameterClasses): \"" + + delegateClassName + "." + methodName + "(" + Arrays.toString(parameterClassNames) + + ")\" must be public.", e); + } catch (NoSuchMethodException e) { + throw new IllegalArgumentException(e.getMessage() + + " delegateClass.delegateMethod(parameterClasses): \"" + + delegateClassName + "." + methodName + "(" + Arrays.toString(parameterClassNames) + + ")\" does not exist.", e); + } + + //static methods do not need a delegateInstance. Non-static methods do. + if(!Modifier.isStatic(this.delegateMethod.getModifiers())) { + try { + this.delegateInstance = delegateClass.newInstance(); + } catch (InstantiationException ex) { + throw new IllegalArgumentException( + " Delegate class \"" + delegateClassName + + "\" must be concrete, because method " + + delegateClassName + "." + methodName + "(" + Arrays.toString(parameterClassNames) + + ") is not static.", ex); + } catch (IllegalAccessException ex) { + new IllegalArgumentException( + " Delegate class \"" + delegateClassName + + "\" must must have a zero-argument constructor, because " + + "method delegateClass.delegateMethod(parameterClasses): \"" + + delegateClassName + "." + methodName + "(" + Arrays.toString(parameterClassNames) + + ")\" is not static.", ex); + } + } else { + this.delegateInstance = null; + } + } + /** + * Convert an array of fully qualified class names into an array of Class objects + * @param parameterClassNames + * @return The Class objects found that match the specified class names provided. + */ + protected final Class[] getParameters(String[] parameterClassNames) { + if (parameterClassNames == null) { + return new Class[0]; + } + Vector classes = new Vector(); + Iterator classNames = new ArrayListIterator(parameterClassNames); + while(classNames.hasNext()) { + classes.add(getClass(classNames.next(), "parameter")); + } + return classes.toArray(new Class[classes.size()]); + } + /** + * Convert a single fully qualified class name into a Class object + * @param className + * @param purpose + * @return The Class matching the specified name, if it exists. + */ + protected final Class getClass(String className, String purpose) { + try { + Class theClass = Class.forName(className); + return theClass; + } catch ( ClassNotFoundException ex ) { + throw new IllegalArgumentException(ex.getMessage() + + " " + purpose + " Class " + className + + " must be in the classpath", ex); + } + } + /** + * Delegates to the method specified in setPolicyParameters + */ + public boolean isAuthorized(Object[] runtimeParameters) throws Exception { + return ((Boolean)delegateMethod.invoke(delegateInstance, runtimeParameters)).booleanValue(); + } +} + + diff --git a/src/main/java/org/owasp/esapi/reference/accesscontrol/DynaBeanACRParameter.java b/src/main/java/org/owasp/esapi/reference/accesscontrol/DynaBeanACRParameter.java new file mode 100644 index 000000000..c0d29f382 --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/accesscontrol/DynaBeanACRParameter.java @@ -0,0 +1,196 @@ +package org.owasp.esapi.reference.accesscontrol; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Date; +import java.util.Iterator; + +import org.apache.commons.beanutils.LazyDynaMap; +import org.owasp.esapi.reference.accesscontrol.policyloader.PolicyParameters; + +/** + * A DynaBean comes from the apache bean utils. It is basically a + * convenient way to dynamically assign getters and setters. Essentially, + * the way we use DynaBean is a HashMap that can be set to read only. + * @author Mike H. Fauzy + */ +public class DynaBeanACRParameter implements PolicyParameters { + protected LazyDynaMap policyProperties; + + public DynaBeanACRParameter() { + policyProperties = new LazyDynaMap(); + } + + /* (non-Javadoc) + * @see org.owasp.esapi.reference.accesscontrol.policyloader.PolicyParameters#get(java.lang.String) + */ + public Object get(String key) { + return policyProperties.get(key); + } + /** + * Convenience method to avoid common casts. + * @param key + * @return The true/false value of the specified key. False if not found. + */ + public boolean getBoolean(String key) { + return ((Boolean)get(key)).booleanValue(); + } + /** + * Convenience method to avoid common casts. + * @param key + * @return The byte value of the specified key. + */ + public byte getByte(String key) { + return ((Byte)get(key)).byteValue(); + } + /** + * Convenience method to avoid common casts. + * @param key + * @return The char value of the specified key. + */ + public char getChar(String key) { + return ((Character)get(key)).charValue(); + } + /** + * Convenience method to avoid common casts. + * @param key + * @return The int value of the specified key. + */ + public int getInt(String key) { + return ((Integer)get(key)).intValue(); + } + /** + * Convenience method to avoid common casts. + * @param key + * @return The long value of the specified key. + */ + public long getLong(String key) { + return ((Long)get(key)).longValue(); + } + /** + * Convenience method to avoid common casts. + * @param key + * @return The float value of the specified key. + */ + public float getFloat(String key) { + return ((Float)get(key)).floatValue(); + } + /** + * Convenience method to avoid common casts. + * @param key + * @return The double value of the specified key. + */ + public double getDouble(String key) { + return ((Double)get(key)).doubleValue(); + } + /** + * Convenience method to avoid common casts. + * @param key + * @return The BigDecimal value of the specified key. + */ + public BigDecimal getBigDecimal(String key) { + return (BigDecimal)get(key); + } + /** + * Convenience method to avoid common casts. + * @param key + * @return The BigInteger value of the specified key. + */ + public BigInteger getBigInteger(String key) { + return (BigInteger)get(key); + } + /** + * Convenience method to avoid common casts. + * @param key + * @return The Date value of the specified key. + */ + public Date getDate(String key) { + return (Date)get(key); + } + + /** + * Convenience method to avoid common casts. Note that the time object + * is the same as a date object + * @param key + * @return The Date value of the specified key. + */ + public Date getTime(String key) { + return (Date)get(key); + } + + /** + * Convenience method to avoid common casts. + * @param key + * @return The String value of the specified key. null if the key is not defined. + */ + public String getString(String key) { + return (String)get(key); + } + + /** + * Convenience method to avoid common casts. + * @param key + * @return The String value of the specified key. If the key is not defined, the default value is returned instead. + */ + public String getString(String key, String defaultValue) { + return (String)get(key) == null ? defaultValue : (String)get(key); + } + + /** + * Convenience method to avoid common casts. + * @param key + * @return The String[] value of the specified key. + */ + public String[] getStringArray(String key) { + return (String[])get(key); + } + + /** + * Convenience method to avoid common casts. + * @param key + * @return The value of the specified key, returned generically as an Object. + */ + public Object getObject(String key) { + return get(key); + } + + /* (non-Javadoc) + * @see org.owasp.esapi.reference.accesscontrol.policyloader.PolicyParameters#set(java.lang.String, java.lang.Object) + */ + public void set(String key, Object value) throws IllegalArgumentException { + policyProperties.set(key, value); + } + /* (non-Javadoc) + * @see org.owasp.esapi.reference.accesscontrol.policyloader.PolicyParameters#put(java.lang.String, java.lang.Object) + */ + public void put(String key, Object value) throws IllegalArgumentException { + set(key, value); + } + + /** + * This makes the map itself read only, but the mutability of objects + * that this map contains is not affected. Specifically, properties + * cannot be added or removed and the reference cannot be changed to + * a different object, but this does not change whether the values that the + * object contains can be changed. + */ + public void lock() { + policyProperties.setRestricted(true); + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + Iterator keys = policyProperties.getMap().keySet().iterator(); + String currentKey; + while(keys.hasNext()) { + currentKey = (String)keys.next(); + sb.append(currentKey); + sb.append("="); + sb.append(policyProperties.get(currentKey)); + if(keys.hasNext()) { + sb.append(","); + } + } + return sb.toString(); + } +} diff --git a/src/main/java/org/owasp/esapi/reference/accesscontrol/EchoRuntimeParameterACR.java b/src/main/java/org/owasp/esapi/reference/accesscontrol/EchoRuntimeParameterACR.java new file mode 100644 index 000000000..2bafc3864 --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/accesscontrol/EchoRuntimeParameterACR.java @@ -0,0 +1,13 @@ +package org.owasp.esapi.reference.accesscontrol; + +public class EchoRuntimeParameterACR extends BaseACR{ + + /** + * Returns true iff runtimeParameter is a Boolean true. + * throws ClassCastException if runtimeParameter is not a Boolean. + */ + public boolean isAuthorized(Boolean runtimeParameter) throws ClassCastException{ + return runtimeParameter.booleanValue(); + } + +} \ No newline at end of file diff --git a/src/main/java/org/owasp/esapi/reference/accesscontrol/ExperimentalAccessController.java b/src/main/java/org/owasp/esapi/reference/accesscontrol/ExperimentalAccessController.java new file mode 100644 index 000000000..0b1e4cfb2 --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/accesscontrol/ExperimentalAccessController.java @@ -0,0 +1,194 @@ +package org.owasp.esapi.reference.accesscontrol; + +import java.util.Map; + +import org.owasp.esapi.AccessControlRule; +import org.owasp.esapi.AccessController; +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Logger; +import org.owasp.esapi.errors.AccessControlException; +import org.owasp.esapi.reference.accesscontrol.policyloader.ACRPolicyFileLoader; +import org.owasp.esapi.reference.accesscontrol.policyloader.PolicyDTO; + +public class ExperimentalAccessController implements AccessController { + private Map ruleMap; + + protected final Logger logger = ESAPI.getLogger("DefaultAccessController"); + + public ExperimentalAccessController(Map ruleMap) { + this.ruleMap = ruleMap; + } + public ExperimentalAccessController() throws AccessControlException { + ACRPolicyFileLoader policyDescriptor = new ACRPolicyFileLoader(); + PolicyDTO policyDTO = policyDescriptor.load(); + ruleMap = policyDTO.getAccessControlRules(); + } + + public boolean isAuthorized(Object key, Object runtimeParameter) { + try { + AccessControlRule rule = (AccessControlRule)ruleMap.get(key); + if(rule == null) { + throw new AccessControlException("Access Denied", + "AccessControlRule was not found for key: " + key); + } + if(logger.isDebugEnabled()){ logger.debug(Logger.EVENT_SUCCESS, "Evaluating Authorization Rule \"" + key + "\" Using class: " + rule.getClass().getCanonicalName()); } + return rule.isAuthorized(runtimeParameter); + } catch(Exception e) { + try { + //Log the exception by throwing and then catching it. + //TODO figure out what which string goes where. + throw new AccessControlException("Access Denied", + "An unhandled Exception was " + + "caught, so access is denied.", + e); + } catch(AccessControlException ace) { + //the exception was just logged. There's nothing left to do. + } + return false; //fail closed + } + } + + public void assertAuthorized(Object key, Object runtimeParameter) + throws AccessControlException { + boolean isAuthorized = false; + try { + AccessControlRule rule = (AccessControlRule)ruleMap.get(key); + if(rule == null) { + throw new AccessControlException("Access Denied", + "AccessControlRule was not found for key: " + key); + } + if(logger.isDebugEnabled()){ logger.debug(Logger.EVENT_SUCCESS, "Asserting Authorization Rule \"" + key + "\" Using class: " + rule.getClass().getCanonicalName()); } + isAuthorized = rule.isAuthorized(runtimeParameter); + } catch(Exception e) { + //TODO figure out what which string goes where. + throw new AccessControlException("Access Denied", "An unhandled Exception was " + + "caught, so access is denied." + + "AccessControlException.", + e); + } + if(!isAuthorized) { + throw new AccessControlException("Access Denied", + "Access Denied for key: " + key + + " runtimeParameter: " + runtimeParameter); + } + } + + /**** Below this line is legacy support ****/ + + /** + * @param action + * @param data + * @throws AccessControlException + * @see org.owasp.esapi.reference.accesscontrol.FileBasedACRs#isAuthorizedForData(java.lang.String, java.lang.Object) + * @deprecated + */ + @Deprecated + public void assertAuthorizedForData(String action, Object data) + throws AccessControlException { + this.assertAuthorized("AC 1.0 Data", new Object[] {action, data}); + } + + /** + * @param filepath + * @throws AccessControlException + * @see org.owasp.esapi.reference.accesscontrol.FileBasedACRs#isAuthorizedForFile(java.lang.String) + * @deprecated + */ + @Deprecated + public void assertAuthorizedForFile(String filepath) + throws AccessControlException { + this.assertAuthorized("AC 1.0 File", new Object[] {filepath}); + } + + /** + * @param functionName + * @throws AccessControlException + * @see org.owasp.esapi.reference.accesscontrol.FileBasedACRs#isAuthorizedForFunction(java.lang.String) + * @deprecated + */ + @Deprecated + public void assertAuthorizedForFunction(String functionName) + throws AccessControlException { + this.assertAuthorized("AC 1.0 Function", new Object[] {functionName}); + } + + /** + * @param serviceName + * @throws AccessControlException + * @see org.owasp.esapi.reference.accesscontrol.FileBasedACRs#isAuthorizedForService(java.lang.String) + * @deprecated + */ + @Deprecated + public void assertAuthorizedForService(String serviceName) + throws AccessControlException { + this.assertAuthorized("AC 1.0 Service", new Object[] {serviceName}); + } + + /** + * @param url + * @throws AccessControlException + * @see org.owasp.esapi.reference.accesscontrol.FileBasedACRs#isAuthorizedForURL(java.lang.String) + * @deprecated + */ + @Deprecated + public void assertAuthorizedForURL(String url) + throws AccessControlException { + this.assertAuthorized("AC 1.0 URL", new Object[] {url}); + } + + /** + * @param action + * @param data + * @return {@code true} if access is permitted; {@code false} otherwise. + * @see org.owasp.esapi.reference.accesscontrol.FileBasedACRs#isAuthorizedForData(java.lang.String, java.lang.Object) + * @deprecated + */ + @Deprecated + public boolean isAuthorizedForData(String action, Object data) { + return this.isAuthorized("AC 1.0 Data", new Object[] {action, data}); + } + + /** + * @param filepath + * @return {@code true} if access is permitted; {@code false} otherwise. + * @see org.owasp.esapi.reference.accesscontrol.FileBasedACRs#isAuthorizedForFile(java.lang.String) + * @deprecated + */ + @Deprecated + public boolean isAuthorizedForFile(String filepath) { + return this.isAuthorized("AC 1.0 File", new Object[] {filepath}); + } + + /** + * @param functionName + * @return {@code true} if access is permitted; {@code false} otherwise. + * @see org.owasp.esapi.reference.accesscontrol.FileBasedACRs#isAuthorizedForFunction(java.lang.String) + * @deprecated + */ + @Deprecated + public boolean isAuthorizedForFunction(String functionName) { + return this.isAuthorized("AC 1.0 Function", new Object[] {functionName}); + } + + /** + * @param serviceName + * @return {@code true} if access is permitted; {@code false} otherwise. + * @see org.owasp.esapi.reference.accesscontrol.FileBasedACRs#isAuthorizedForService(java.lang.String) + * @deprecated + */ + @Deprecated + public boolean isAuthorizedForService(String serviceName) { + return this.isAuthorized("AC 1.0 Service", new Object[] {serviceName}); + } + + /** + * @param url + * @return {@code true} if access is permitted; {@code false} otherwise. + * @see org.owasp.esapi.reference.accesscontrol.FileBasedACRs#isAuthorizedForURL(java.lang.String) + * @deprecated + */ + @Deprecated + public boolean isAuthorizedForURL(String url) { + return this.isAuthorized("AC 1.0 URL", new Object[] {url}); + } +} diff --git a/src/main/java/org/owasp/esapi/reference/accesscontrol/FileBasedACRs.java b/src/main/java/org/owasp/esapi/reference/accesscontrol/FileBasedACRs.java new file mode 100644 index 000000000..2e19304f5 --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/accesscontrol/FileBasedACRs.java @@ -0,0 +1,559 @@ +/** + * 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.reference.accesscontrol; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Logger; +import org.owasp.esapi.User; +import org.owasp.esapi.errors.AccessControlException; +import org.owasp.esapi.errors.EncodingException; +import org.owasp.esapi.errors.IntrusionException; + +// CHECKME: If this exists for backward compatibility, should this +// class be deprecated??? If so, mark it using annotation. +/** + * This class exists for backwards compatibility with the AccessController 1.0 + * reference implementation. + * + * 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 AccessController 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 control 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 AccessController 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 /
  • + *
+ * + * @author Mike Fauzy (mike.fauzy@aspectsecurity.com) + * @author Jeff Williams (jeff.williams@aspectsecurity.com) + * @since June 1, 2007 + */ +public class FileBasedACRs { + + /** The url map. */ + private Map urlMap = new HashMap(); + + /** The function map. */ + private Map functionMap = new HashMap(); + + /** The data map. */ + private Map dataMap = new HashMap(); + + /** The file map. */ + private Map fileMap = new HashMap(); + + /** The service map. */ + private Map serviceMap = new HashMap(); + + /** A rule containing "deny". */ + private Rule deny = new Rule(); + + /** The logger. */ + private Logger logger = ESAPI.getLogger("FileBasedACRs"); + + /** + * Check if URL is authorized. + * @param url The URL tested for authorization + * @return {@code true} if access is allowed, {@code false} otherwise. + */ + public boolean isAuthorizedForURL(String url) { + if (urlMap==null || urlMap.isEmpty()) { + urlMap = loadRules("URLAccessRules.txt"); + } + return matchRule(urlMap, url); + } + + /** + * TODO Javadoc + */ + public boolean isAuthorizedForFunction(String functionName) throws AccessControlException { + if (functionMap==null || functionMap.isEmpty()) { + functionMap = loadRules("FunctionAccessRules.txt"); + } + return matchRule(functionMap, functionName); + } + + /** + * TODO Javadoc + */ + public boolean isAuthorizedForData(String action, Object data) throws AccessControlException{ + if (dataMap==null || dataMap.isEmpty()) { + dataMap = loadDataRules("DataAccessRules.txt"); + } + return matchRule(dataMap, (Class)data, action); + } + + /** + * TODO Javadoc + */ + public boolean isAuthorizedForFile(String filepath) throws AccessControlException { + if (fileMap==null || fileMap.isEmpty()) { + fileMap = loadRules("FileAccessRules.txt"); + } + return matchRule(fileMap, filepath.replaceAll("\\\\","/")); + } + + /** + * TODO Javadoc + */ + public boolean isAuthorizedForService(String serviceName) throws AccessControlException { + if (serviceMap==null || serviceMap.isEmpty()) { + serviceMap = loadRules("ServiceAccessRules.txt"); + } + return matchRule(serviceMap, serviceName); + } + + /** + * Checks to see if the current user has access to the specified data, File, Object, etc. + * If the User has access, as specified by the map parameter, this method returns true. If the + * User does not have access or an exception is thrown, false is returned. + * + * @param map + * the map containing access rules + * @param path + * the path of the requested File, URL, Object, etc. + * + * @return + * true, if the user has access, false otherwise + * + */ + private boolean matchRule(Map map, String path) { + // get users roles + User user = ESAPI.authenticator().getCurrentUser(); + Set roles = user.getRoles(); + // search for the first rule that matches the path and rules + Rule rule = searchForRule(map, roles, path); + return rule.allow; + } + + /** + * Checks to see if the current user has access to the specified Class and action. + * If the User has access, as specified by the map parameter, this method returns true. + * If the User does not have access or an exception is thrown, false is returned. + * + * @param map + * the map containing access rules + * @param clazz + * the Class being requested for access + * @param action + * the action the User has asked to perform + * @return + * true, if the user has access, false otherwise + * + */ + private boolean matchRule(Map map, Class clazz, String action) { + // get users roles + User user = ESAPI.authenticator().getCurrentUser(); + Set roles = user.getRoles(); + // search for the first rule that matches the path and rules + Rule rule = searchForRule(map, roles, clazz, action); + return rule != null; + } + + /** + * Search for rule. Four mapping rules are used in 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 servlet, specified by the single character pattern / + * + * @param map + * the map containing access rules + * @param roles + * the roles of the User being checked for access + * @param path + * the File, URL, Object, etc. being checked for access + * + * @return + * the rule stating whether to allow or deny access + * + */ + private Rule searchForRule(Map map, Set roles, String path) { + String canonical = ESAPI.encoder().canonicalize(path); + + String part = canonical; + if ( part == null ) { + part = ""; + } + + while (part.endsWith("/")) { + part = part.substring(0, part.length() - 1); + } + + if (part.indexOf("..") != -1) { + throw new IntrusionException("Attempt to manipulate access control path", "Attempt to manipulate access control path: " + path ); + } + + // extract extension if any + String extension = ""; + int extIndex = part.lastIndexOf("."); + if (extIndex != -1) { + extension = part.substring(extIndex + 1); + } + + // Check for exact match - ignore any ending slash + Rule rule = (Rule) map.get(part); + + // Check for ending with /* + if (rule == null) + rule = (Rule) map.get(part + "/*"); + + // Check for matching extension rule *.ext + if (rule == null) + rule = (Rule) map.get("*." + extension); + + // if rule found and user's roles match rules' roles, return the rule + if (rule != null && overlap(rule.roles, roles)) + return rule; + + // rule hasn't been found - if there are no more parts, return a deny + int slash = part.lastIndexOf('/'); + if ( slash == -1 ) { + return deny; + } + + // if there are more parts, strip off the last part and recurse + part = part.substring(0, part.lastIndexOf('/')); + + // return default deny + if (part.length() <= 1) { + return deny; + } + + return searchForRule(map, roles, part); + } + + /** + * Search for rule. Searches the specified access map to see if any of the roles specified have + * access to perform the specified action on the specified Class. + * + * @param map + * the map containing access rules + * @param roles + * the roles used to determine access level + * @param clazz + * the Class being requested for access + * @param action + * the action the User has asked to perform + * + * @return + * the rule that allows the specified roles access to perform the requested action on the specified Class, or null if access is not granted + * + */ + private Rule searchForRule(Map map, Set roles, Class clazz, String action) { + + // Check for exact match - ignore any ending slash + Rule rule = (Rule) map.get(clazz); + if( ( rule != null ) && ( overlap(rule.actions, action) ) && ( overlap(rule.roles, roles) )){ + return rule; + } + return null; + } + + /** + * Return true if there is overlap between the two sets. This method merely checks to see if + * ruleRoles contains any of the roles listed in userRoles. + * + * @param ruleRoles + * the rule roles + * @param userRoles + * the user roles + * + * @return + * true, if any roles exist in both Sets. False otherwise. + */ + private boolean overlap(Set ruleRoles, Set userRoles) { + if (ruleRoles.contains("any")) { + return true; + } + Iterator i = userRoles.iterator(); + while (i.hasNext()) { + String role = (String) i.next(); + if (ruleRoles.contains(role)) { + return true; + } + } + return false; + } + + /** + * This method merely checks to see if ruleActions contains the action requested. + * + * @param ruleActions + * actions listed for a rule + * @param action + * the action requested that will be searched for in ruleActions + * + * @return + * true, if any action exists in ruleActions. False otherwise. + */ + private boolean overlap( List ruleActions, String action){ + if( ruleActions.contains(action) ) + return true; + return false; + } + + /** + * Checks that the roles passed in contain only letters, numbers, and underscores. Also checks that + * roles are no more than 10 characters long. If a role does not pass validation, it is not included in the + * list of roles returned by this method. A log warning is also generated for any invalid roles. + * + * @param roles + * roles to validate according to criteria started above + * @return + * a List of roles that are valid according to the criteria stated above. + * + */ + private List validateRoles(List roles){ + List ret = new ArrayList(); + for(int x = 0; x < roles.size(); x++){ + String canonical = ESAPI.encoder().canonicalize(((String)roles.get(x)).trim()); + + if(!ESAPI.validator().isValidInput("Validating user roles in FileBasedAccessController", canonical, "RoleName", 20, false)) { + logger.warning( Logger.SECURITY_FAILURE, "Role: " + ((String)roles.get(x)).trim() + " is invalid, so was not added to the list of roles for this Rule."); + } else { + ret.add(canonical.trim()); + } + } + return ret; + } + + /** + * Loads access rules by storing them in a hashmap. This method begins reading the File specified by + * the ruleset parameter, ignoring any lines that begin with '#' characters as comments. Sections of the access rules file + * are split by the pipe character ('|'). The method loads all paths, replacing '\' characters with '/' for uniformity then loads + * the list of comma separated roles. The roles are validated to be sure they are within a + * length and character set, specified in the validateRoles(String) method. Then the permissions are stored for each item in the rules list. + * If the word "allow" appears on the line, the specified roles are granted access to the data - otherwise, they will be denied access. + * + * Each path may only appear once in the access rules file. Any entry, after the first, containing the same path will be logged and ignored. + * + * @param ruleset + * the name of the data that contains access rules + * + * @return + * a hash map containing the ruleset + */ + private Map loadRules(String ruleset) { + ruleset = "fbac-policies/" + ruleset; + Map map = new HashMap(); + InputStream is = null; + try { + is = ESAPI.securityConfiguration().getResourceStream(ruleset); + String line = ""; + while ((line = ESAPI.validator().safeReadLine(is, 500)) != null) { + if (line.length() > 0 && line.charAt(0) != '#') { + Rule rule = new Rule(); + String[] parts = line.split("\\|"); + // fix Windows paths + rule.path = parts[0].trim().replaceAll("\\\\", "/"); + + List roles = commaSplit(parts[1].trim().toLowerCase()); + roles = validateRoles(roles); + for(int x = 0; x < roles.size(); x++) + rule.roles.add(((String)roles.get(x)).trim()); + + String action = parts[2].trim(); + rule.allow = action.equalsIgnoreCase("allow"); + if (map.containsKey(rule.path)) { + logger.warning( Logger.SECURITY_FAILURE, "Problem in access control file. Duplicate rule ignored: " + rule); + } else { + map.put(rule.path, rule); + } + } + } + } catch (Exception e) { + logger.warning( Logger.SECURITY_FAILURE, "Problem in access control file: " + ruleset, e ); + } finally { + try { + if (is != null) { + is.close(); + } + } catch (IOException e) { + logger.warning(Logger.SECURITY_FAILURE, "Failure closing access control file: " + ruleset, e); + } + } + return map; + } + + /** + * Loads access rules by storing them in a hashmap. This method begins reading the File specified by + * the ruleset parameter, ignoring any lines that begin with '#' characters as comments. Sections of the access rules file + * are split by the pipe character ('|'). The method then loads all Classes, loads the list of comma separated roles, then the list of comma separated actions. + * The roles are validated to be sure they are within a length and character set, specified in the validateRoles(String) method. + * + * Each path may only appear once in the access rules file. Any entry, after the first, containing the same path will be logged and ignored. + * + * @param ruleset + * the name of the data that contains access rules + * + * @return + * a hash map containing the ruleset + */ + private Map loadDataRules(String ruleset) { + Map map = new HashMap(); + InputStream is = null; + + try { + ruleset = "fbac-policies/" + ruleset; + is = ESAPI.securityConfiguration().getResourceStream(ruleset); + String line = ""; + while ((line = ESAPI.validator().safeReadLine(is, 500)) != null) { + if (line.length() > 0 && line.charAt(0) != '#') { + Rule rule = new Rule(); + String[] parts = line.split("\\|"); + rule.clazz = Class.forName(parts[0].trim()); + + List roles = commaSplit(parts[1].trim().toLowerCase()); + roles = validateRoles(roles); + for(int x = 0; x < roles.size(); x++) + rule.roles.add(((String)roles.get(x)).trim()); + + List action = commaSplit(parts[2].trim().toLowerCase()); + for(int x = 0; x < action.size(); x++) + rule.actions.add(((String) action.get(x)).trim()); + + if (map.containsKey(rule.path)) { + logger.warning( Logger.SECURITY_FAILURE, "Problem in access control file. Duplicate rule ignored: " + rule); + } else { + map.put(rule.clazz, rule); + } + } + } + } catch (Exception e) { + logger.warning( Logger.SECURITY_FAILURE, "Problem in access control file : " + ruleset, e ); + } finally { + + try { + if (is != null) { + is.close(); + } + } catch (IOException e) { + logger.warning(Logger.SECURITY_FAILURE, "Failure closing access control file : " + ruleset, e); + } + } + return map; + } + + /** + * This method splits a String by the ',' and returns the result as a List. + * + * @param input + * the String to split by ',' + * @return + * a List where each entry was on either side of a ',' in the original String + */ + private List commaSplit(String input){ + String[] array = input.split(","); + return Arrays.asList(array); + } + + /** + * The Class Rule. + */ + private class Rule { + + + protected String path = ""; + + + protected Set roles = new HashSet(); + + + protected boolean allow = false; + + + protected Class clazz = null; + + + protected List actions = new ArrayList(); + + /** + * + * Creates a new Rule object. + */ + protected Rule() { + // to replace synthetic accessor method + } + + /** + * {@inheritDoc} + */ + public String toString() { + return "URL:" + path + " | " + roles + " | " + (allow ? "allow" : "deny"); + } + } +} diff --git a/src/main/java/org/owasp/esapi/reference/accesscontrol/policyloader/ACRParameterLoader.java b/src/main/java/org/owasp/esapi/reference/accesscontrol/policyloader/ACRParameterLoader.java new file mode 100644 index 000000000..a0ae77f95 --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/accesscontrol/policyloader/ACRParameterLoader.java @@ -0,0 +1,9 @@ +package org.owasp.esapi.reference.accesscontrol.policyloader; + +import org.apache.commons.configuration.XMLConfiguration; + + +public interface ACRParameterLoader { + public abstract T getParameters(XMLConfiguration config, int currentRule) + throws java.lang.Exception; //TODO this exception could be more specific +} diff --git a/src/main/java/org/owasp/esapi/reference/accesscontrol/policyloader/ACRParameterLoaderHelper.java b/src/main/java/org/owasp/esapi/reference/accesscontrol/policyloader/ACRParameterLoaderHelper.java new file mode 100644 index 000000000..d0846fc2a --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/accesscontrol/policyloader/ACRParameterLoaderHelper.java @@ -0,0 +1,46 @@ +package org.owasp.esapi.reference.accesscontrol.policyloader; + +import org.apache.commons.configuration.XMLConfiguration; + +final public class ACRParameterLoaderHelper { + + public static Object getParameterValue(XMLConfiguration config, int currentRule, int currentParameter, String parameterType) throws Exception { + String key = "AccessControlRules.AccessControlRule(" + + currentRule + ").Parameters.Parameter(" + currentParameter + ")[@value]"; + Object parameterValue; + if("String".equalsIgnoreCase(parameterType)) { + parameterValue = config.getString(key); + } else if("StringArray".equalsIgnoreCase(parameterType)) { + parameterValue = config.getStringArray(key); + } else if("Boolean".equalsIgnoreCase(parameterType)){ + parameterValue = config.getBoolean(key); + } else if("Byte".equalsIgnoreCase(parameterType)){ + parameterValue = config.getByte(key); + } else if("Int".equalsIgnoreCase(parameterType)){ + parameterValue = config.getInt(key); + } else if("Long".equalsIgnoreCase(parameterType)){ + parameterValue = config.getLong(key); + } else if("Float".equalsIgnoreCase(parameterType)){ + parameterValue = config.getFloat(key); + } else if("Double".equalsIgnoreCase(parameterType)){ + parameterValue = config.getDouble(key); + } else if("BigDecimal".equalsIgnoreCase(parameterType)){ + parameterValue = config.getBigDecimal(key); + } else if("BigInteger".equalsIgnoreCase(parameterType)){ + parameterValue = config.getBigInteger(key); + } else if("Date".equalsIgnoreCase(parameterType)){ + parameterValue = java.text.DateFormat.getDateInstance().parse(config.getString(key)); + } else if("Time".equalsIgnoreCase(parameterType)){ + java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("h:mm a"); + parameterValue = sdf.parseObject(config.getString(key)); +// parameterValue = java.text.DateFormat.getTimeInstance().parse(config.getString(key)); + } + //add timestamp. check for other stuff. + else { + throw new IllegalArgumentException("Unable to load the key \"" + key + + "\", because " + "the type \"" + parameterType + + "\" was not recognized." ); + } + return parameterValue; + } +} diff --git a/src/main/java/org/owasp/esapi/reference/accesscontrol/policyloader/ACRPolicyFileLoader.java b/src/main/java/org/owasp/esapi/reference/accesscontrol/policyloader/ACRPolicyFileLoader.java new file mode 100644 index 000000000..9a7f5955b --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/accesscontrol/policyloader/ACRPolicyFileLoader.java @@ -0,0 +1,99 @@ +package org.owasp.esapi.reference.accesscontrol.policyloader; + +import java.io.File; +import java.util.Collection; + +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.XMLConfiguration; +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Logger; +import org.owasp.esapi.errors.AccessControlException; + +final public class ACRPolicyFileLoader { + protected final Logger logger = ESAPI.getLogger("ACRPolicyFileLoader"); + + public PolicyDTO load() throws AccessControlException { + PolicyDTO policyDTO = new PolicyDTO(); + XMLConfiguration config; + File file = ESAPI.securityConfiguration().getResourceFile("ESAPI-AccessControlPolicy.xml"); + try + { + config = new XMLConfiguration(file); + } + catch(ConfigurationException cex) + { + if(file == null) { + throw new AccessControlException("Unable to load configuration file for the following: " + "ESAPI-AccessControlPolicy.xml", "", cex); + } + throw new AccessControlException("Unable to load configuration file from the following location: " + file.getAbsolutePath(), "", cex); + } + + Object property = config.getProperty("AccessControlRules.AccessControlRule[@name]"); + logger.info(Logger.EVENT_SUCCESS, "Loading Property: " + property); + int numberOfRules = 0; + if(property instanceof Collection) { + numberOfRules = ((Collection)property).size(); + } //implied else property == null -> return new PolicyDTO + + String ruleName = ""; + String ruleClass = ""; + Object rulePolicyParameter = null; + int currentRule = 0; + try { + logger.info(Logger.EVENT_SUCCESS, "Number of rules: " + numberOfRules); + for(currentRule = 0; currentRule < numberOfRules; currentRule++) { + logger.trace(Logger.EVENT_SUCCESS, "----"); + ruleName = config.getString("AccessControlRules.AccessControlRule(" + currentRule + ")[@name]"); + logger.trace(Logger.EVENT_SUCCESS, "Rule name: " + ruleName); + ruleClass = config.getString("AccessControlRules.AccessControlRule(" + currentRule + ")[@class]"); + logger.trace(Logger.EVENT_SUCCESS, "Rule Class: " + ruleClass); + rulePolicyParameter = getPolicyParameter(config, currentRule); + logger.trace(Logger.EVENT_SUCCESS, "rulePolicyParameters: " + rulePolicyParameter); + policyDTO.addAccessControlRule( + ruleName, + ruleClass, + rulePolicyParameter); + } + logger.info(Logger.EVENT_SUCCESS, "policyDTO loaded: " + policyDTO); + } catch (Exception e) { + throw new AccessControlException("Unable to load AccessControlRule parameter. " + + " Rule number: " + currentRule + + " Probably: Rule.name: " + ruleName + + " Probably: Rule.class: " + ruleClass + + e.getMessage(), "", e); + } + return policyDTO; + } + + protected Object getPolicyParameter(XMLConfiguration config, int currentRule) + throws ClassNotFoundException, IllegalAccessException, InstantiationException, Exception { + //If there aren't any properties: short circuit and return null. +// Properties tempParameters = config.getProperties("AccessControlRules.AccessControlRule(" + currentRule + ").Parameters.Parameter[@name]"); + Object property = config.getProperty("AccessControlRules.AccessControlRule(" + currentRule + ").Parameters.Parameter[@name]"); + if(property == null) { + return null; + } + + int numberOfProperties = 0; + if(property instanceof Collection) { + numberOfProperties = ((Collection)property).size(); + } else { + numberOfProperties = 1; + } + logger.info(Logger.EVENT_SUCCESS, "Number of properties: " + numberOfProperties); + + if(numberOfProperties < 1) { + return null; + } + String parametersLoaderClassName = config.getString("AccessControlRules.AccessControlRule(" + currentRule + ").Parameters[@parametersLoader]"); + if("".equals(parametersLoaderClassName) || parametersLoaderClassName == null) { + //this default should have a properties file override option + parametersLoaderClassName = "org.owasp.esapi.reference.accesscontrol.policyloader.DynaBeanACRParameterLoader"; + } + logger.info(Logger.EVENT_SUCCESS, "Parameters Loader:" + parametersLoaderClassName); + ACRParameterLoader acrParamaterLoader = + (ACRParameterLoader) + Class.forName(parametersLoaderClassName).newInstance(); + return acrParamaterLoader.getParameters(config, currentRule); + } +} \ No newline at end of file diff --git a/src/main/java/org/owasp/esapi/reference/accesscontrol/policyloader/DynaBeanACRParameterLoader.java b/src/main/java/org/owasp/esapi/reference/accesscontrol/policyloader/DynaBeanACRParameterLoader.java new file mode 100644 index 000000000..14174625d --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/accesscontrol/policyloader/DynaBeanACRParameterLoader.java @@ -0,0 +1,30 @@ +package org.owasp.esapi.reference.accesscontrol.policyloader; + +import org.apache.commons.configuration.XMLConfiguration; +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Logger; +import org.owasp.esapi.reference.accesscontrol.DynaBeanACRParameter; + +import static org.owasp.esapi.reference.accesscontrol.policyloader.ACRParameterLoaderHelper.getParameterValue; + +final public class DynaBeanACRParameterLoader + implements ACRParameterLoader { + + Logger logger = ESAPI.getLogger(this.getClass()); + +// @Override + public DynaBeanACRParameter getParameters(XMLConfiguration config, int currentRule) throws java.lang.Exception { //TODO reduce the exception + DynaBeanACRParameter policyParameter = new DynaBeanACRParameter(); + int numberOfParameters = config.getList("AccessControlRules.AccessControlRule(" + currentRule + ").Parameters.Parameter[@name]").size(); + for(int currentParameter = 0; currentParameter < numberOfParameters; currentParameter++) { + String parameterName = config.getString("AccessControlRules.AccessControlRule(" + currentRule + ").Parameters.Parameter(" + currentParameter + ")[@name]"); + String parameterType = config.getString("AccessControlRules.AccessControlRule(" + currentRule + ").Parameters.Parameter(" + currentParameter + ")[@type]"); + Object parameterValue = getParameterValue(config, currentRule, currentParameter, parameterType); + policyParameter.set(parameterName, parameterValue); + } + policyParameter.lock(); //This line makes the policyParameter read only. + logger.info(Logger.SECURITY_SUCCESS, "Loaded " + numberOfParameters + + " parameters: " + policyParameter.toString()); + return policyParameter; + } +} diff --git a/src/main/java/org/owasp/esapi/reference/accesscontrol/policyloader/EchoDynaBeanPolicyParameterACR.java b/src/main/java/org/owasp/esapi/reference/accesscontrol/policyloader/EchoDynaBeanPolicyParameterACR.java new file mode 100644 index 000000000..f30919c71 --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/accesscontrol/policyloader/EchoDynaBeanPolicyParameterACR.java @@ -0,0 +1,15 @@ +package org.owasp.esapi.reference.accesscontrol.policyloader; + +import org.owasp.esapi.reference.accesscontrol.BaseACR; +import org.owasp.esapi.reference.accesscontrol.DynaBeanACRParameter; + +//public class EchoDynaBeanPolicyParameterACR extends BaseDynaBeanACR { +public class EchoDynaBeanPolicyParameterACR extends BaseACR { + /** + * Returns true if runtimeParameter is a Boolean true. + * throws ClassCastException if runtimeParameter is not a Boolean. + */ + public boolean isAuthorized(Object runtimeParameter) throws ClassCastException{ + return getPolicyParameters().getBoolean("isTrue"); + } +} \ No newline at end of file diff --git a/src/main/java/org/owasp/esapi/reference/accesscontrol/policyloader/PolicyDTO.java b/src/main/java/org/owasp/esapi/reference/accesscontrol/policyloader/PolicyDTO.java new file mode 100644 index 000000000..7be99150b --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/accesscontrol/policyloader/PolicyDTO.java @@ -0,0 +1,55 @@ +package org.owasp.esapi.reference.accesscontrol.policyloader; + +import java.lang.reflect.Constructor; +import java.util.HashMap; +import java.util.Map; + +import org.owasp.esapi.AccessControlRule; +import org.owasp.esapi.errors.AccessControlException; + +/** + * The point of the loaders is to create this + * @author Mike H. Fauzy + * + */ +final public class PolicyDTO { + private Map accessControlRules; + + public PolicyDTO() { + this.accessControlRules = new HashMap(); + } + + public Map getAccessControlRules() { + return accessControlRules; + } + + public void addAccessControlRule(String key, String accessControlRuleClassName, + Object policyParameter) throws AccessControlException { + if (accessControlRules.get(key) != null) { + throw new AccessControlException("Duplicate keys are not allowed. " + + "Key: " + key, ""); + } + Constructor accessControlRuleConstructor; + try { + + + Class accessControlRuleClass = Class.forName(accessControlRuleClassName, false, this.getClass().getClassLoader()); + accessControlRuleConstructor = accessControlRuleClass + .getConstructor(); + AccessControlRule accessControlRule = + (AccessControlRule) accessControlRuleConstructor + .newInstance(); + accessControlRule.setPolicyParameters(policyParameter); + accessControlRules.put(key, accessControlRule); + } catch (Exception e) { + throw new AccessControlException( + "Unable to create Access Control Rule for key: \"" + key + + "\" with policyParameters: \"" + policyParameter + "\"", + "", + e); + } + } + public String toString() { + return accessControlRules.toString(); + } +} diff --git a/src/main/java/org/owasp/esapi/reference/accesscontrol/policyloader/PolicyParameters.java b/src/main/java/org/owasp/esapi/reference/accesscontrol/policyloader/PolicyParameters.java new file mode 100644 index 000000000..65175f878 --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/accesscontrol/policyloader/PolicyParameters.java @@ -0,0 +1,42 @@ +package org.owasp.esapi.reference.accesscontrol.policyloader; + +public interface PolicyParameters { + + /** + * Follows the contract for java.util.Map; + * @param key + * @return The Object referred to by this key, if it exists. + * @see java.util.Map + */ + public abstract Object get(String key); + + /** + * This works just like a Map, except it will throw an exception if lock() + * has been called. + * @param key + * @param value + * @throws IllegalArgumentException if this DynaBeanACRParameter instance + * has already been locked. + */ + public abstract void set(String key, Object value) + throws IllegalArgumentException; + + /** + * This is a convenience method for developers that prefer to think of this + * as a map instead of being bean-like. + * + * @see #set(String, Object) + */ + public abstract void put(String key, Object value) + throws IllegalArgumentException; + + /** + * This makes the map itself read only, but the mutability of objects + * that this map contains is not affected. Specifically, properties + * cannot be added or removed and the reference cannot be changed to + * a different object, but this does not change whether the values that the + * object contains can be changed. + */ + public abstract void lock(); + +} \ No newline at end of file diff --git a/src/main/java/org/owasp/esapi/reference/crypto/DefaultEncryptedProperties.java b/src/main/java/org/owasp/esapi/reference/crypto/DefaultEncryptedProperties.java new file mode 100644 index 000000000..397088915 --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/crypto/DefaultEncryptedProperties.java @@ -0,0 +1,216 @@ +/** + * 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.reference.crypto; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.util.Iterator; +import java.util.Properties; +import java.util.Set; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Logger; +import org.owasp.esapi.crypto.CipherText; +import org.owasp.esapi.crypto.PlainText; +import org.owasp.esapi.errors.EncryptionException; + +/** + * Reference implementation of the {@code EncryptedProperties} interface. This + * implementation wraps a normal properties file, and creates surrogates for the + * {@code getProperty} and {@code setProperty} methods that perform encryption + * and decryption based on {@code 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. + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @author kevin.w.wall@gmail.com + * @since June 1, 2007 + * @see org.owasp.esapi.EncryptedProperties + * @see org.owasp.esapi.reference.crypto.ReferenceEncryptedProperties + */ +public class DefaultEncryptedProperties implements org.owasp.esapi.EncryptedProperties { + + /** The properties. */ + private final Properties properties = new Properties(); + + /** The logger. */ + private final Logger logger = ESAPI.getLogger("EncryptedProperties"); + + /** + * Instantiates a new encrypted properties. + */ + public DefaultEncryptedProperties() { + // hidden + } + + /** + * {@inheritDoc} + */ + public synchronized String getProperty(String key) throws EncryptionException { + String[] errorMsgs = new String[] { + ": failed decoding from base64", + ": failed to deserialize properly", + ": failed to decrypt properly" + }; + + int progressMark = 0; + try { + String encryptedValue = properties.getProperty(key); + + if(encryptedValue==null) + return null; + + progressMark = 0; + byte[] serializedCiphertext = ESAPI.encoder().decodeFromBase64(encryptedValue); + progressMark++; + CipherText restoredCipherText = CipherText.fromPortableSerializedBytes(serializedCiphertext); + progressMark++; + PlainText plaintext = ESAPI.encryptor().decrypt(restoredCipherText); + + return plaintext.toString(); + } catch (Exception e) { + throw new EncryptionException("Property retrieval failure", + "Couldn't retrieve encrypted property for property " + key + + errorMsgs[progressMark], e); + } + } + + /** + * {@inheritDoc} + */ + public synchronized String setProperty(String key, String value) throws EncryptionException { + String[] errorMsgs = new String[] { + ": failed to encrypt properly", + ": failed to serialize correctly", + ": failed to base64-encode properly", + ": failed to set base64-encoded value as property. Illegal key name?" + }; + + int progressMark = 0; + try { + if ( key == null ) { + throw new NullPointerException("Property name may not be null."); + } + if ( value == null ) { + throw new NullPointerException("Property value may not be null."); + } + // NOTE: Not backward compatible w/ ESAPI 1.4. + PlainText pt = new PlainText(value); + CipherText ct = ESAPI.encryptor().encrypt(pt); + progressMark++; + byte[] serializedCiphertext = ct.asPortableSerializedByteArray(); + progressMark++; + String b64str = ESAPI.encoder().encodeForBase64(serializedCiphertext, false); + progressMark++; + String encryptedValue = (String)properties.setProperty(key, b64str); + progressMark++; + return encryptedValue; + } catch (Exception e) { + throw new EncryptionException("Property setting failure", + "Couldn't set encrypted property " + key + + errorMsgs[progressMark], e); + } + } + + /** + * {@inheritDoc} + */ + public Set keySet() { + return properties.keySet(); + } + + /** + * {@inheritDoc} + */ + public void load(InputStream in) throws IOException { + properties.load(in); + logger.trace(Logger.SECURITY_SUCCESS, "Encrypted properties loaded successfully"); + } + + /** + * {@inheritDoc} + */ + public void store(OutputStream out, String comments) throws IOException { + properties.store(out, comments); + } + + /** + * Loads encrypted properties file based on the location passed in args then prompts the + * user to input key-value pairs. When the user enters a null or blank key, the values + * are stored to the properties file. + * + * @param args + * the location of the properties file to load and write to + * + * @throws Exception + * Any exception thrown + * @deprecated Use {@code EncryptedPropertiesUtils} instead, which allows creating, reading, + * and writing encrypted properties. {@code main} method will be removed in a + * future release. + */ + @Deprecated + public static void main(String[] args) throws Exception { + File f = new File(args[0]); + ESAPI.getLogger( "EncryptedProperties.main" ).debug(Logger.SECURITY_SUCCESS, "Loading encrypted properties from " + f.getAbsolutePath() ); + if ( !f.exists() ) throw new IOException( "Properties file not found: " + f.getAbsolutePath() ); + ESAPI.getLogger( "EncryptedProperties.main" ).debug(Logger.SECURITY_SUCCESS, "Encrypted properties found in " + f.getAbsolutePath() ); + DefaultEncryptedProperties ep = new DefaultEncryptedProperties(); + + FileInputStream in = null; + FileOutputStream out = null; + try { + in = new FileInputStream(f); + out = new FileOutputStream(f); + + ep.load(in); + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + String key = null; + do { + System.out.print("Enter key: "); + key = br.readLine(); + System.out.print("Enter value: "); + String value = br.readLine(); + if (key != null && key.length() > 0 && value != null && value.length() > 0) { + ep.setProperty(key, value); + } + } while (key != null && key.length() > 0); + ep.store(out, "Encrypted Properties File"); + } finally { + // FindBugs and PMD both complain about these next lines, that they may + // ignore thrown exceptions. Really!!! That's the whole point. + try { if ( in != null ) in.close(); } catch( Exception e ) {} + try { if ( out != null ) out.close(); } catch( Exception e ) {} + } + + Iterator i = ep.keySet().iterator(); + while (i.hasNext()) { + String k = (String) i.next(); + String value = ep.getProperty(k); + System.out.println(" " + k + "=" + value); + } + } + +} diff --git a/src/main/java/org/owasp/esapi/reference/crypto/EncryptedPropertiesUtils.java b/src/main/java/org/owasp/esapi/reference/crypto/EncryptedPropertiesUtils.java new file mode 100644 index 000000000..dee385ff1 --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/crypto/EncryptedPropertiesUtils.java @@ -0,0 +1,212 @@ +package org.owasp.esapi.reference.crypto; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.util.Properties; + +import org.owasp.esapi.EncryptedProperties; + +/** + * Command line utilities for reading, writing and creating encrypted properties files. + *

+ * Usage:
+ * + * java org.owasp.esapi.reference.crypto.EncryptedPropertiesUtils [--in file] [--out file] + * [--in-encrypted true|false] [--verbose true|false] + * + *

+ * Command line parameters:
+ *

    + *
  • --in (Optional) Encrypted or plaintext file to read from. If no input file is specified, a new properties file will be created.
  • + *
  • --out (Optional) Encrypted file to output to. Default: Overwrite input file
  • + *
  • --in-encrypted (Optional) True if the input file is encrypted. Default: true
  • + *
  • --verbose (Optional) If true, output (potentially unencrypted) information to the terminal. Default: false
  • + *
+ * + * @author August Detlefsen (augustd at codemagi dot com) + * CodeMagi, Inc. + * @since October 8, 2010 + * @see org.owasp.esapi.EncryptedProperties + */ +public class EncryptedPropertiesUtils { + + /** + * Loads encrypted or plaintext properties file based on the location passed in args + * then prompts the user to input key-value pairs. When the user enters a null or + * blank key, the values are stored to the properties file. + * + * @throws Exception Any exception thrown + */ + public static void main(String[] args) throws Exception { + + //command line options + String inFile = null; + String outFile = null; + boolean inFileEncrypted = true; + boolean verbose = false; + + //parse command line params + for (int i = 0; i < args.length; i = i + 2) { + String paramType = args[i]; + + if ("--in".equals(paramType) && args.length >= i + 1) { + inFile = args[i + 1]; + + } else if ("--out".equals(paramType) && args.length >= i + 1) { + outFile = args[i + 1]; + + } else if ("--in-encrypted".equals(paramType) && args.length >= i + 1) { + inFileEncrypted = Boolean.valueOf(args[i + 1]); + + } else if ("--verbose".equals(paramType) && args.length >= i + 1) { + verbose = Boolean.valueOf(args[i + 1]); + } + + } + + if (outFile == null) { + outFile = inFile; //if no output file is specified we will overwrite the input file + } + if (outFile == null) { + //no input or output file specified. Can't continue. + System.out.println("You must specify an input file or output file"); + System.exit(1); + } + + //load in existing properties from a file + Properties props = loadProperties(inFile, inFileEncrypted); + + //read user input and add keys and values to the property file + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + String key = null; + do { + System.out.print("Enter key: "); + key = br.readLine(); + + if (props.containsKey(key)) { + System.out.print("Key already exists. Replace? "); + String confirm = br.readLine(); + if (!("y".equals(confirm) || "yes".equals(confirm))) { + continue; + } + } + + System.out.print("Enter value: "); + String value = br.readLine(); + + addProperty(props, key, value); + + } while (key != null && key.length() > 0); + + //save output file + storeProperties(outFile, props, + "Encrypted Properties File generated by org.owasp.esapi.reference.crypto.EncryptedPropertiesUtils"); + + System.out.println("Encrypted Properties file output to " + outFile); + + if (verbose) { + for (Object oKey : props.keySet()) { + String sKey = (String) oKey; + String value = props.getProperty(sKey); + System.out.println(" " + sKey + "=" + value); + } + } + + } + + /** + * Loads a Properties file from a filename. If the filename is unspecified + * or the file could not be found, a new Properties is returned. + * + * @param inFile Filename to load Properties from. + * @param inFileEncrypted If true, the input file is assumed to be already encrypted. Default true. + * @return Either the loaded Properties object or a new one if the file could not be found. + * @throws IOException + */ + public static Properties loadProperties(String inFile, Boolean inFileEncrypted) throws IOException { + + if (inFileEncrypted == null) inFileEncrypted = true; + + Properties props; + + if (inFile != null) { + + File f = new File(inFile); + if (!f.exists()) { + System.out.println("Input properties file not found. Creating new."); + props = new ReferenceEncryptedProperties(); + + } else { + String encrypted = inFileEncrypted ? "Encrypted" : "Plaintext"; + System.out.println(encrypted + " properties found in " + f.getAbsolutePath()); + + Properties inProperties; + if (inFileEncrypted) { + inProperties = new ReferenceEncryptedProperties(); + } else { + inProperties = new Properties(); + } + + InputStream in = null; + try { + in = new FileInputStream(f); + inProperties.load(in); + } finally { + try { + if (in != null) in.close(); //quietly close the InputStream + } catch (Exception e) {} + } + + //Use the existing properties + props = new ReferenceEncryptedProperties(inProperties); + } + } else { + System.out.println("Input properties file not found. Creating new."); + props = new ReferenceEncryptedProperties(); + } + + return props; + } + + /** + * Stores a Properties object to a file. + * + * @param outFile Filename to store to + * @param props Properties to store + * @param message A message to add to the comments in the stored file + * @throws Exception + */ + public static void storeProperties(String outFile, Properties props, String message) throws Exception { + OutputStream out = null; + try { + out = new FileOutputStream(new File(outFile)); + props.store(out, message); + } finally { + try { + if (out != null) out.close(); //quietly close OutputStream + } catch (Exception e) {} + } + } + + /** + * Adds a new key-value property to the passed Properties object + * + * @param props The Properties object to add to + * @param key The key to add + * @param value The value to set + * @return The previous value of the property, or null if it is newly added. + */ + public static Object addProperty(Properties props, String key, String value) { + if (props != null && key != null && key.length() > 0 && value != null && value.length() > 0) { + return props.setProperty(key, value); + } + return null; + } + +} diff --git a/src/main/java/org/owasp/esapi/reference/crypto/JavaEncryptor.java b/src/main/java/org/owasp/esapi/reference/crypto/JavaEncryptor.java new file mode 100644 index 000000000..81ff5b0e5 --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/crypto/JavaEncryptor.java @@ -0,0 +1,1029 @@ +/** + * 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 + * @author kevin.w.wall@gmail.com + * @created 2007 + */ +package org.owasp.esapi.reference.crypto; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.PrivateKey; +import java.security.Provider; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.Security; +import java.security.Signature; +import java.util.Date; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.Map.Entry; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +// import javax.crypto.Mac; // Uncomment if computeHMAC() is included. +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; +import javax.crypto.spec.IvParameterSpec; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.EncoderConstants; +import org.owasp.esapi.Encryptor; +import org.owasp.esapi.Logger; +import org.owasp.esapi.codecs.Hex; +import org.owasp.esapi.crypto.CipherSpec; +import org.owasp.esapi.crypto.CipherText; +import org.owasp.esapi.crypto.CryptoHelper; +import org.owasp.esapi.crypto.KeyDerivationFunction; +import org.owasp.esapi.crypto.PlainText; +import org.owasp.esapi.crypto.SecurityProviderLoader; +import org.owasp.esapi.errors.ConfigurationException; +import org.owasp.esapi.errors.EncryptionException; +import org.owasp.esapi.errors.IntegrityException; +import org.owasp.esapi.reference.DefaultSecurityConfiguration; + +/** + * Reference implementation of the {@code Encryptor} interface. This implementation + * layers on the JCE provided cryptographic package. Algorithms used are + * configurable in the {@code ESAPI.properties} file. The main property + * controlling the selection of this class is {@code ESAPI.Encryptor}. Most of + * the other encryption related properties have property names that start with + * the string "Encryptor.". + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @author kevin.w.wall@gmail.com + * @author Chris Schmidt (chrisisbeef .at. gmail.com) + * @since June 1, 2007; some methods since ESAPI Java 2.0 + * @see org.owasp.esapi.Encryptor + */ +public final class JavaEncryptor implements Encryptor { + private static volatile Encryptor singletonInstance; + + // Note: This double-check pattern only works because singletonInstance + // is declared to be volatile. Usually this method is called + // via ESAPI.encryptor() rather than directly. + public static Encryptor getInstance() throws EncryptionException { + if ( singletonInstance == null ) { + synchronized ( JavaEncryptor.class ) { + if ( singletonInstance == null ) { + singletonInstance = new JavaEncryptor(); + } + } + } + return singletonInstance; + } + + private static boolean initialized = false; + + // encryption + private static SecretKeySpec secretKeySpec = null; // DISCUSS: Why static? Implies one key?!? + private static String encryptAlgorithm = "AES"; + private static String encoding = "UTF-8"; + private static int encryptionKeyLength = 128; + + // digital signatures + private static PrivateKey privateKey = null; + private static PublicKey publicKey = null; + private static String signatureAlgorithm = "SHA256withDSA"; + private static String randomAlgorithm = "SHA1PRNG"; // SHA1 is fine as a CSRNG. + private static int signatureKeyLength = 2048; + + // hashing + private static String hashAlgorithm = "SHA-512"; + private static int hashIterations = 1024; + + // Logging - DISCUSS: This "sticks" us with a specific logger to whatever it was when + // this class is first loaded. Is this a big limitation? Since there + // is no method to reset it, we may has well make it 'final' also. + private static Logger logger = ESAPI.getLogger("JavaEncryptor"); + // Used to print out warnings about deprecated methods. + private static int encryptCounter = 0; + private static int decryptCounter = 0; + // DISCUSS: OK to not have a property for this to set the frequency? + // The desire is to persuade people to move away from these + // two deprecated encrypt(String) / decrypt(String) methods, + // so perhaps the annoyance factor of not being able to + // change it will help. For now, it is just hard-coded here. + // We could be mean and just print a warning *every* time. + private static final int logEveryNthUse = 25; + + // *Only* use this string for user messages for EncryptionException when + // decryption fails. This is to prevent information leakage that may be + // valuable in various forms of ciphertext attacks, such as the + // Padded Oracle attack described by Rizzo and Duong. + private static final String DECRYPTION_FAILED = "Decryption failed; see logs for details."; + + // # of seconds that all failed decryption attempts will take. Used to + // help prevent side-channel timing attacks. + private static int N_SECS = 2; + + // Load the preferred JCE provider if one has been specified. + static { + try { + SecurityProviderLoader.loadESAPIPreferredJCEProvider(); + } catch (NoSuchProviderException ex) { + // Note that audit logging is done elsewhere in called method. + logger.fatal(Logger.SECURITY_FAILURE, + "JavaEncryptor failed to load preferred JCE provider.", ex); + throw new ExceptionInInitializerError(ex); + } + setupAlgorithms(); + } + + /** + * Generates a new strongly random secret key and salt that can be + * copy and pasted in the ESAPI.properties file. + * + * @param args Set first argument to "-print" to display available algorithms on standard output. + * @throws java.lang.Exception To cover a multitude of sins, mostly in configuring ESAPI.properties. + */ + public static void main( String[] args ) throws Exception { + System.out.println( "Generating a new secret master key" ); + + // print out available ciphers + if ( args.length == 1 && args[0].equalsIgnoreCase("-print" ) ) { + System.out.println( "AVAILABLE ALGORITHMS" ); + + Provider[] providers = Security.getProviders(); + TreeMap tm = new TreeMap(); + // DISCUSS: Note: We go through multiple providers, yet nowhere do I + // see where we print out the PROVIDER NAME. Not all providers + // will implement the same algorithms and some "partner" with + // whom we are exchanging different cryptographic messages may + // have _different_ providers in their java.security file. So + // it would be useful to know the provider name where each + // algorithm is implemented. Might be good to prepend the provider + // name to the 'key' with something like "providerName: ". Thoughts? + for (int i = 0; i != providers.length; i++) { + // DISCUSS: Print security provider name here??? + // Note: For some odd reason, Provider.keySet() returns + // Set of the property keys (which are Strings) + // contained in this provider, but Set seems + // more appropriate. But that's why we need the cast below. + System.out.println("===== Provider " + i + ":" + providers[i].getName() + " ======"); + Iterator it = providers[i].keySet().iterator(); + while (it.hasNext()) { + String key = (String)it.next(); + String value = providers[i].getProperty( key ); + tm.put(key, value); + System.out.println("\t\t " + key + " -> "+ value ); + } + } + + Set< Entry > keyValueSet = tm.entrySet(); + Iterator> it = keyValueSet.iterator(); + while( it.hasNext() ) { + Map.Entry entry = it.next(); + String key = entry.getKey(); + String value = entry.getValue(); + System.out.println( " " + key + " -> "+ value ); + } + } else { + // Used to print a similar line to use '-print' even when it was specified. + System.out.println( "\tuse '-print' to also show available crypto algorithms from all the security providers" ); + } + + // setup algorithms -- Each of these have defaults if not set, although + // someone could set them to something invalid. If + // so a suitable exception will be thrown and displayed. + encryptAlgorithm = ESAPI.securityConfiguration().getEncryptionAlgorithm(); + encryptionKeyLength = ESAPI.securityConfiguration().getEncryptionKeyLength(); + randomAlgorithm = ESAPI.securityConfiguration().getRandomAlgorithm(); + + SecureRandom random = SecureRandom.getInstance(randomAlgorithm); + SecretKey secretKey = CryptoHelper.generateSecretKey(encryptAlgorithm, encryptionKeyLength); + byte[] raw = secretKey.getEncoded(); + byte[] salt = new byte[20]; // Or 160-bits; big enough for SHA1, but not SHA-256 or SHA-512. + random.nextBytes( salt ); + String eol = System.getProperty("line.separator", "\n"); // So it works on Windows too. + System.out.println( eol + "Copy and paste these lines into your ESAPI.properties" + eol); + System.out.println( "#=============================================================="); + System.out.println( "Encryptor.MasterKey=" + ESAPI.encoder().encodeForBase64(raw, false) ); + System.out.println( "Encryptor.MasterSalt=" + ESAPI.encoder().encodeForBase64(salt, false) ); + System.out.println( "#==============================================================" + eol); + } + + + /** + * Private CTOR for {@code JavaEncryptor}, called by {@code getInstance()}. + * @throws EncryptionException if can't construct this object for some reason. + * Original exception will be attached as the 'cause'. + */ + private JavaEncryptor() throws EncryptionException { + byte[] salt = ESAPI.securityConfiguration().getMasterSalt(); + byte[] skey = ESAPI.securityConfiguration().getMasterKey(); + + if ( salt == null ) { + throw new ConfigurationException("Can't obtain master salt, Encryptor.MasterSalt"); + } + + if ( salt.length < 16 ) { + throw new ConfigurationException("Encryptor.MasterSalt must be at least 16 bytes. " + + "Length is: " + salt.length + " bytes."); + } + + if ( skey == null ) { + throw new ConfigurationException("Can't obtain master key, Encryptor.MasterKey"); + } + + if ( skey.length < 7 ) { + throw new ConfigurationException("Encryptor.MasterKey must be at least 7 bytes. " + + "Length is: " + skey.length + " bytes."); + } + + // Set up secretKeySpec for use for symmetric encryption and decryption, + // and set up the public/private keys for asymmetric encryption / + // decryption. + // TODO: Note: Since we've dumped ESAPI 1.4 crypto backward compatibility, + // then we probably can ditch the Encryptor.EncryptionAlgorithm + // property. If so, encryptAlgorithm should probably use + // Encryptor.CipherTransformation and just pull off the cipher + // algorithm name so we can use it here. That just requires + // advance notice and proper deprecation, which I'm not prepared + // to do at this time. -kevin wall + synchronized(JavaEncryptor.class) { + if ( ! initialized ) { + // + // For symmetric encryption + // + // NOTE: FindBugs complains about this + // (ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD) but + // it should be OK since it is synchronized and only + // done once. While we could separate this out and + // handle in a static initializer, it just seems to + // fit better here. + secretKeySpec = new SecretKeySpec(skey, encryptAlgorithm ); + + // + // For asymmetric encryption (i.e., public/private key) + // + try { + SecureRandom prng = SecureRandom.getInstance(randomAlgorithm); + + // Because hash() is not static (but it could be were in not + // for the interface method specification in Encryptor), we + // cannot do this initialization in a static method or static + // initializer. + byte[] seed = hash(new String(skey, encoding),new String(salt, encoding)).getBytes(encoding); + prng.setSeed(seed); + initKeyPair(prng); + } catch (Exception e) { + throw new EncryptionException("Encryption failure", "Error creating Encryptor", e); + } + + // Mark everything as initialized. + initialized = true; + } + } + } + + + + /** + * {@inheritDoc} + * + * Hashes the data with the supplied salt and the number of iterations specified in + * the ESAPI SecurityConfiguration. + */ + public String hash(String plaintext, String salt) throws EncryptionException { + return hash( plaintext, salt, hashIterations ); + } + + /** + * {@inheritDoc} + * + * 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 the specified number of iterations + * in order to help strengthen weak passwords. + */ + public String hash(String plaintext, String salt, int iterations) throws EncryptionException { + byte[] bytes = null; + try { + MessageDigest digest = MessageDigest.getInstance(hashAlgorithm); + digest.reset(); + digest.update(ESAPI.securityConfiguration().getMasterSalt()); + digest.update(salt.getBytes(encoding)); + digest.update(plaintext.getBytes(encoding)); + + // rehash a number of times to help strengthen weak passwords + bytes = digest.digest(); + for (int i = 0; i < iterations; i++) { + digest.reset(); + bytes = digest.digest(bytes); + } + String encoded = ESAPI.encoder().encodeForBase64(bytes,false); + return encoded; + } catch (NoSuchAlgorithmException e) { + throw new EncryptionException("Internal error", "Can't find hash algorithm " + hashAlgorithm, e); + } catch (UnsupportedEncodingException ex) { + throw new EncryptionException("Internal error", "Can't find encoding for " + encoding, ex); + } + } + + /** + * {@inheritDoc} + */ + public CipherText encrypt(PlainText plaintext) throws EncryptionException { + // Now more of a convenience function for using the master key. + return encrypt(secretKeySpec, plaintext); + } + + /** + * {@inheritDoc} + */ + public CipherText encrypt(SecretKey key, PlainText plain) + throws EncryptionException + { + if ( key == null ) { + throw new IllegalArgumentException("(Master) encryption key arg may not be null. Is Encryptor.MasterKey set?"); + } + if ( plain == null ) { + throw new IllegalArgumentException("PlainText may arg not be null"); + } + byte[] plaintext = plain.asBytes(); + boolean overwritePlaintext = ESAPI.securityConfiguration().overwritePlainText(); + + boolean success = false; // Used in 'finally' clause. + String xform = null; + int keySize = key.getEncoded().length * 8; // Convert to # bits + + try { + xform = ESAPI.securityConfiguration().getCipherTransformation(); + String[] parts = xform.split("/"); + if ( parts.length != 3 ) { + throw new ConfigurationException("Malformed cipher transformation: " + xform + + ". Should have format of cipher_alg/cipher_mode/padding_scheme."); + } + String cipherMode = parts[1]; + + // This way we can prevent modes like OFB and CFB where the IV should never + // be repeated with the same encryption key (at least until we support + // Encryptor.ChooseIVMethod=specified and allow us to specify some mechanism + // to ensure the IV will never be repeated (such as a time stamp or other + // monotonically increasing function). + // DISCUSS: Should we include the permitted cipher modes in the exception msg? + if ( ! CryptoHelper.isAllowedCipherMode(cipherMode) ) { + throw new EncryptionException("Encryption failure: invalid cipher mode ( " + cipherMode + ") for encryption", + "Encryption failure: Cipher transformation " + xform + " specifies invalid " + + "cipher mode " + cipherMode); + } + + // Note - Cipher is not thread-safe so we create one locally + // Also, we need to change this eventually so other algorithms can + // be supported. Eventually, there will be an encrypt() method that + // takes a (new class) CryptoControls, as something like this: + // public CipherText encrypt(CryptoControls ctrl, SecretKey skey, PlainText plaintext) + // and this method will just call that one. + Cipher encrypter = Cipher.getInstance(xform); + String cipherAlg = encrypter.getAlgorithm(); + + int minKeyLen = 112; // Use for hard-coded default to support 2TDEA + try { + minKeyLen = ESAPI.securityConfiguration().getIntProp("Encryptor.MinEncryptionKeyLength"); + } catch( Exception ex ) { + logger.warning(Logger.EVENT_FAILURE, + "Property 'Encryptor.MinEncryptionKeyLength' not properly set in ESAPI.properties file; using hard coded default of 112 for min key size for encryption.", + ex); + ; // Do NOT rethrow. + } + + if ( keySize < minKeyLen ) { + // NOTE: This used to just log a warning. It now logs an error & throws an exception. + // + // ESAPI.EncryptionKeyLength defaults to 128. This means that someone wants to use ESAPI to + // encrypt with something like 2-key TDES, they would have to set this to that property + // to 112 bits. + logger.error(Logger.SECURITY_FAILURE, "Actual key size of " + keySize + " bits SMALLER THAN MINIMUM allowed " + + "encryption key length (ESAPI.EncryptionKeyLength) of " + minKeyLen + " bits with cipher algorithm " + cipherAlg); + throw new ConfigurationException("Actual key size of " + keySize + " bits smaller than specified " + + "encryption key length (ESAPI.EncryptionKeyLength) of " + minKeyLen + " bits."); + } + if ( keySize < 112 ) { // NIST Special Pub 800-57 considers 112-bits to be the minimally safe key size from 2010-2030. + // Note that 112 bits 'just happens' to be size of 2-key Triple DES! So for example, if they + // have configured ESAPI's Encryptor.EncryptionKeyLength to (say) 56 bits, we are going to + // nag them like their mother! :) + logger.warning(Logger.SECURITY_FAILURE, "Potentially insecure encryption. Key size of " + keySize + "bits " + + "not sufficiently long for " + cipherAlg + ". Should use appropriate algorithm with key size " + + "of *at least* 112 bits except when required by legacy apps. See NIST Special Pub 800-57."); + } + // Check if algorithm mentioned in SecretKey is same as that being used for Cipher object. + // They should be the same. If they are different, things could fail. (E.g., DES and DESede + // require keys with even parity. Even if key was sufficient size, if it didn't have the correct + // parity it could fail.) + // + String skeyAlg = key.getAlgorithm(); + if ( !( cipherAlg.startsWith( skeyAlg + "/" ) || cipherAlg.equals( skeyAlg ) ) ) { + // DISCUSS: Should we thrown a ConfigurationException here or just log a warning??? I'm game for + // either, but personally I'd prefer the squeaky wheel to the annoying throwing of + // a ConfigurationException (which is a RuntimeException). Less likely to upset + // the development community. + logger.warning(Logger.SECURITY_FAILURE, "Encryption mismatch between cipher algorithm (" + + cipherAlg + ") and SecretKey algorithm (" + skeyAlg + "). Cipher will use algorithm " + cipherAlg); + } + + byte[] ivBytes = null; + CipherSpec cipherSpec = new CipherSpec(encrypter, keySize); // Could pass the ACTUAL (intended) key size + + // Using cipher mode that supports *both* confidentiality *and* authenticity? If so, then + // use the specified SecretKey as-is rather than computing a derived key from it. We also + // don't expect a separate MAC in the specified CipherText object so therefore don't try + // to validate it. + boolean preferredCipherMode = CryptoHelper.isCombinedCipherMode( cipherMode ); + SecretKey encKey = null; + if ( preferredCipherMode ) { + encKey = key; + } else { + encKey = computeDerivedKey(KeyDerivationFunction.kdfVersion, getDefaultPRF(), + key, keySize, "encryption"); + } + + if ( cipherSpec.requiresIV() ) { + String ivType = ESAPI.securityConfiguration().getIVType(); + IvParameterSpec ivSpec = null; + if ( ivType.equalsIgnoreCase("random") ) { + ivBytes = ESAPI.randomizer().getRandomBytes(encrypter.getBlockSize()); + } else { + // This really shouldn't happen here. Show catch it a few + // lines above. + throw new ConfigurationException("Property Encryptor.ChooseIVMethod must be set to 'random'."); + } + ivSpec = new IvParameterSpec(ivBytes); + cipherSpec.setIV(ivBytes); + encrypter.init(Cipher.ENCRYPT_MODE, encKey, ivSpec); + } else { + encrypter.init(Cipher.ENCRYPT_MODE, encKey); + } + logger.debug(Logger.EVENT_SUCCESS, "Encrypting with " + cipherSpec); + byte[] raw = encrypter.doFinal(plaintext); + // Convert to CipherText. + CipherText ciphertext = new CipherText(cipherSpec, raw); + + // If we are using a "preferred" cipher mode--i.e., one that supports *both* confidentiality and + // authenticity, there is no point to store a separate MAC in the CipherText object. Thus we only + // do this when we are not using such a cipher mode. + if ( !preferredCipherMode ) { + // Compute derived key, and then use it to compute and store separate MAC in CipherText object. + SecretKey authKey = computeDerivedKey(KeyDerivationFunction.kdfVersion, getDefaultPRF(), + key, keySize, "authenticity"); + ciphertext.computeAndStoreMAC( authKey ); + } + logger.debug(Logger.EVENT_SUCCESS, "JavaEncryptor.encrypt(SecretKey,byte[],boolean,boolean) -- success!"); + success = true; // W00t!!! + return ciphertext; + } catch (InvalidKeyException ike) { + throw new EncryptionException("Encryption failure: Invalid key exception.", + "Requested key size: " + keySize + "bits greater than 128 bits. Must install unlimited strength crypto extension from Sun: " + + ike.getMessage(), ike); + } catch (ConfigurationException cex) { + throw new EncryptionException("Encryption failure: Configuration error. Details in log.", "Key size mismatch or unsupported IV method. " + + "Check encryption key size vs. ESAPI.EncryptionKeyLength or Encryptor.ChooseIVMethod property.", cex); + } catch (InvalidAlgorithmParameterException e) { + throw new EncryptionException("Encryption failure (invalid IV)", + "Encryption problem: Invalid IV spec: " + e.getMessage(), e); + } catch (IllegalBlockSizeException e) { + throw new EncryptionException("Encryption failure (no padding used; invalid input size)", + "Encryption problem: Invalid input size without padding (" + xform + "). " + e.getMessage(), e); + } catch (BadPaddingException e) { + throw new EncryptionException("Encryption failure", + "[Note: Should NEVER happen in encryption mode.] Encryption problem: " + e.getMessage(), e); + } catch (NoSuchAlgorithmException e) { + throw new EncryptionException("Encryption failure (unavailable cipher requested)", + "Encryption problem: specified algorithm in cipher xform " + xform + " not available: " + e.getMessage(), e); + } catch (NoSuchPaddingException e) { + throw new EncryptionException("Encryption failure (unavailable padding scheme requested)", + "Encryption problem: specified padding scheme in cipher xform " + xform + " not available: " + e.getMessage(), e); + } finally { + // Don't overwrite anything in the case of exceptions because they may wish to retry. + if ( success && overwritePlaintext ) { + plain.overwrite(); // Note: Same as overwriting 'plaintext' byte array. + } + } + } + + /** + * {@inheritDoc} + */ + public PlainText decrypt(CipherText ciphertext) throws EncryptionException { + // Now more of a convenience function for using the master key. + return decrypt(secretKeySpec, ciphertext); + } + + /** + * {@inheritDoc} + */ + public PlainText decrypt(SecretKey key, CipherText ciphertext) + throws EncryptionException, IllegalArgumentException + { + long start = System.nanoTime(); // Current time in nanosecs; used to prevent timing attacks + if ( key == null ) { + throw new IllegalArgumentException("SecretKey arg may not be null"); + } + if ( ciphertext == null ) { + throw new IllegalArgumentException("Ciphertext may arg not be null"); + } + + if ( ! CryptoHelper.isAllowedCipherMode(ciphertext.getCipherMode()) ) { + // This really should be an illegal argument exception, but it could + // mean that a partner encrypted something using a cipher mode that + // you do not accept, so it's a bit more complex than that. Also + // throwing an IllegalArgumentException doesn't allow us to provide + // the two separate error messages or automatically log it. + throw new EncryptionException(DECRYPTION_FAILED, + "Invalid cipher mode " + ciphertext.getCipherMode() + + " not permitted for decryption or encryption operations."); + } + logger.debug(Logger.EVENT_SUCCESS, + "Args valid for JavaEncryptor.decrypt(SecretKey,CipherText): " + + ciphertext); + + PlainText plaintext = null; + boolean caughtException = false; + int progressMark = 0; + try { + // First we validate the MAC. + boolean valid = CryptoHelper.isCipherTextMACvalid(key, ciphertext); + if ( !valid ) { + try { + // This is going to fail, but we want the same processing + // to occur as much as possible so as to prevent timing + // attacks. We _could_ just be satisfied by the additional + // sleep in the 'finally' clause, but an attacker on the + // same server who can run something like 'ps' can tell + // CPU time versus when the process is sleeping. Hence we + // try to make this as close as possible. Since we know + // it is going to fail, we ignore the result and ignore + // the (expected) exception. + handleDecryption(key, ciphertext); // Ignore return (should fail). + } catch(Exception ex) { + ; // Ignore + } + throw new EncryptionException(DECRYPTION_FAILED, + "Decryption failed because MAC invalid for " + + ciphertext); + } + progressMark++; + // The decryption only counts if the MAC was valid. + plaintext = handleDecryption(key, ciphertext); + progressMark++; + } catch(EncryptionException ex) { + caughtException = true; + String logMsg = null; + switch( progressMark ) { + case 1: + logMsg = "Decryption failed because MAC invalid. See logged exception for details."; + break; + case 2: + logMsg = "Decryption failed because handleDecryption() failed. See logged exception for details."; + break; + default: + logMsg = "Programming error: unexpected progress mark == " + progressMark; + break; + } + logger.error(Logger.SECURITY_FAILURE, logMsg); + throw ex; // Re-throw + } + finally { + if ( caughtException ) { + // The rest of this code is to try to account for any minute differences + // in the time it might take for the various reasons that decryption fails + // in order to prevent any other possible timing attacks. Perhaps it is + // going overboard. If nothing else, if N_SECS is large enough, it might + // deter attempted repeated attacks by making them take much longer. + long now = System.nanoTime(); + long elapsed = now - start; + final long NANOSECS_IN_SEC = 1000000000L; // nanosec is 10**-9 sec + long nSecs = N_SECS * NANOSECS_IN_SEC; // N seconds in nano seconds + if ( elapsed < nSecs ) { + // Want to sleep so total time taken is N seconds. + long extraSleep = nSecs - elapsed; + + // 'extraSleep' is in nanoseconds. Need to convert to a millisec + // part and nanosec part. Nanosec is 10**-9, millsec is + // 10**-3, so divide by (10**-9 / 10**-3), or 10**6 to + // convert to from nanoseconds to milliseconds. + long millis = extraSleep / 1000000L; + long nanos = (extraSleep - (millis * 1000000L)); + + // N_SECS is hard-coded so assertion should be okay here. + assert nanos >= 0 && nanos <= Integer.MAX_VALUE : + "Nanosecs out of bounds; nanos = " + nanos; + try { + Thread.sleep(millis, (int)nanos); + } catch(InterruptedException ex) { + ; // Ignore + } + } // Else ... time already exceeds N_SECS sec, so do not sleep. + } + } + return plaintext; + } + + // Handle the actual decryption portion. At this point it is assumed that + // any MAC has already been validated. (But see "DISCUSS" issue, below.) + private PlainText handleDecryption(SecretKey key, CipherText ciphertext) + throws EncryptionException + { + int keySize = 0; + try { + Cipher decrypter = Cipher.getInstance(ciphertext.getCipherTransformation()); + keySize = key.getEncoded().length * 8; // Convert to # bits + + // Using cipher mode that supports *both* confidentiality *and* authenticity? If so, then + // use the specified SecretKey as-is rather than computing a derived key from it. We also + // don't expect a separate MAC in the specified CipherText object so therefore don't try + // to validate it. + boolean preferredCipherMode = CryptoHelper.isCombinedCipherMode( ciphertext.getCipherMode() ); + SecretKey encKey = null; + if ( preferredCipherMode ) { + encKey = key; + } else { + // TODO: PERFORMANCE: Calculate avg time this takes and consider caching for very short interval + // (e.g., 2 to 5 sec tops). Otherwise doing lots of encryptions in a loop could take a LOT longer. + // But remember Jon Bentley's "Rule #1 on performance: First make it right, then make it fast." + // This would be a security trade-off as it would leave keys in memory a bit longer, so it + // should probably be off by default and controlled via a property. + // + // TODO: Feed in some additional parms here to use as the 'context' for the + // KeyDerivationFunction...especially the KDF version. We would have to + // store that in the CipherText object. We *possibly* could make it + // transient so it would not be serialized with the CipherText object, + // otherwise we would have to implement readObject() and writeObject() + // methods there to support backward compatibility. Anyhow the intent + // is to prevent down grade attacks when we finally re-design and + // re-implement the MAC. Think about this in version 2.1.1. + encKey = computeDerivedKey( ciphertext.getKDFVersion(), ciphertext.getKDF_PRF(), + key, keySize, "encryption"); + } + if ( ciphertext.requiresIV() ) { + decrypter.init(Cipher.DECRYPT_MODE, encKey, new IvParameterSpec(ciphertext.getIV())); + } else { + decrypter.init(Cipher.DECRYPT_MODE, encKey); + } + byte[] output = decrypter.doFinal(ciphertext.getRawCipherText()); + return new PlainText(output); + + } catch (InvalidKeyException ike) { + throw new EncryptionException(DECRYPTION_FAILED, "Must install JCE Unlimited Strength Jurisdiction Policy Files from Sun", ike); + } catch (NoSuchAlgorithmException e) { + throw new EncryptionException(DECRYPTION_FAILED, "Invalid algorithm for available JCE providers - " + + ciphertext.getCipherTransformation() + ": " + e.getMessage(), e); + } catch (NoSuchPaddingException e) { + throw new EncryptionException(DECRYPTION_FAILED, "Invalid padding scheme (" + + ciphertext.getPaddingScheme() + ") for cipher transformation " + ciphertext.getCipherTransformation() + + ": " + e.getMessage(), e); + } catch (InvalidAlgorithmParameterException e) { + throw new EncryptionException(DECRYPTION_FAILED, "Decryption problem: " + e.getMessage(), e); + } catch (IllegalBlockSizeException e) { + throw new EncryptionException(DECRYPTION_FAILED, "Decryption problem: " + e.getMessage(), e); + } catch (BadPaddingException e) { + // DISCUSS: This needs fixed. Already validated MAC in CryptoHelper.isCipherTextMACvalid() above. + // So only way we could get a padding exception is if invalid padding were used originally by + // the party doing the encryption. (This might happen with a buggy padding scheme for instance.) + // It *seems* harmless though, so will leave it for now, and technically, we need to either catch it + // or declare it in a throws class. Clearly we don't want to do the later. This should be discussed + // during a code inspection. + SecretKey authKey; + try { + authKey = computeDerivedKey( ciphertext.getKDFVersion(), ciphertext.getKDF_PRF(), + key, keySize, "authenticity"); + } catch (Exception e1) { + throw new EncryptionException(DECRYPTION_FAILED, + "Decryption problem -- failed to compute derived key for authenticity: " + e1.getMessage(), e1); + } + boolean success = ciphertext.validateMAC( authKey ); + if ( success ) { + throw new EncryptionException(DECRYPTION_FAILED, "Decryption problem: " + e.getMessage(), e); + } else { + throw new EncryptionException(DECRYPTION_FAILED, + "Decryption problem: WARNING: Adversary may have tampered with " + + "CipherText object orCipherText object mangled in transit: " + e.getMessage(), e); + } + } + } + + /** + * {@inheritDoc} + */ + public String sign(String data) throws EncryptionException { + try { + Signature signer = Signature.getInstance(signatureAlgorithm); + signer.initSign(privateKey); + signer.update(data.getBytes(encoding)); + byte[] bytes = signer.sign(); + return ESAPI.encoder().encodeForBase64(bytes, false); + } catch (InvalidKeyException ike) { + throw new EncryptionException("Encryption failure", "Must install unlimited strength crypto extension from Sun", ike); + } catch (Exception e) { + throw new EncryptionException("Signature failure", "Can't find signature algorithm " + signatureAlgorithm, e); + } + } + + /** + * {@inheritDoc} + */ + public boolean verifySignature(String signature, String data) { + try { + byte[] bytes = ESAPI.encoder().decodeFromBase64(signature); + Signature signer = Signature.getInstance(signatureAlgorithm); + signer.initVerify(publicKey); + signer.update(data.getBytes(encoding)); + return signer.verify(bytes); + } catch (Exception e) { + // NOTE: EncryptionException constructed *only* for side-effect of causing logging. + // FindBugs complains about this and since it examines byte-code, there's no way to + // shut it up. + new EncryptionException("Invalid signature", "Problem verifying signature: " + e.getMessage(), e); + return false; + } + } + + /** + * {@inheritDoc} + * + * @param expiration + * @throws IntegrityException + */ + public String seal(String data, long expiration) throws IntegrityException { + if ( data == null ) { + throw new IllegalArgumentException("Data to be sealed may not be null."); + } + + try { + String b64data = null; + try { + b64data = ESAPI.encoder().encodeForBase64(data.getBytes("UTF-8"), false); + } catch (UnsupportedEncodingException e) { + ; // Ignore; should never happen since UTF-8 built into rt.jar + } + // mix in some random data so even identical data and timestamp produces different seals + String nonce = ESAPI.randomizer().getRandomString(10, EncoderConstants.CHAR_ALPHANUMERICS); + String plaintext = expiration + ":" + nonce + ":" + b64data; + // add integrity check; signature is already base64 encoded. + String sig = this.sign( plaintext ); + CipherText ciphertext = this.encrypt( new PlainText(plaintext + ":" + sig) ); + String sealedData = ESAPI.encoder().encodeForBase64(ciphertext.asPortableSerializedByteArray(), false); + return sealedData; + } catch( EncryptionException e ) { + throw new IntegrityException( e.getUserMessage(), e.getLogMessage(), e ); + } + } + + /** + * {@inheritDoc} + */ + public String unseal(String seal) throws EncryptionException { + PlainText plaintext = null; + try { + byte[] encryptedBytes = ESAPI.encoder().decodeFromBase64(seal); + CipherText cipherText = null; + try { + cipherText = CipherText.fromPortableSerializedBytes(encryptedBytes); + } catch( AssertionError e) { + // Some of the tests in EncryptorTest.testVerifySeal() are examples of + // this if assertions are enabled, but otherwise it should not + // normally happen. + throw new EncryptionException("Invalid seal", + "Seal passed garbarge data resulting in AssertionError: " + e); + } + plaintext = this.decrypt(cipherText); + + String[] parts = plaintext.toString().split(":"); + if (parts.length != 4) { + throw new EncryptionException("Invalid seal", "Seal was not formatted properly."); + } + + String timestring = parts[0]; + long now = new Date().getTime(); + long expiration = Long.parseLong(timestring); + if (now > expiration) { + throw new EncryptionException("Invalid seal", "Seal expiration date of " + new Date(expiration) + " has past."); + } + String nonce = parts[1]; + String b64data = parts[2]; + String sig = parts[3]; + if (!this.verifySignature(sig, timestring + ":" + nonce + ":" + b64data ) ) { + throw new EncryptionException("Invalid seal", "Seal integrity check failed"); + } + return new String(ESAPI.encoder().decodeFromBase64(b64data), "UTF-8"); + } catch (EncryptionException e) { + throw e; + } catch (Exception e) { + throw new EncryptionException("Invalid seal", "Invalid seal:" + e.getMessage(), e); + } + } + + + /** + * {@inheritDoc} + */ + public boolean verifySeal( String seal ) { + try { + unseal( seal ); + return true; + } catch( EncryptionException e ) { + return false; + } + } + + /** + * {@inheritDoc} + */ + public long getTimeStamp() { + return new Date().getTime(); + } + + /** + * {@inheritDoc} + */ + public long getRelativeTimeStamp( long offset ) { + return new Date().getTime() + offset; + } + + // DISCUSS: Why experimental? Would have to be added to Encryptor interface + // but only 3 things I saw wrong with this was 1) it used HMacMD5 instead + // of HMacSHA1 (see discussion below), 2) that the HMac key is the + // same one used for encryption (also see comments), and 3) it caught + // overly broad exceptions. Here it is with these specific areas + // addressed, but no unit testing has been done at this point. -kww + /** + * Compute an HMAC for a String. Experimental. + * @param input The input for which to compute the HMac. + */ +/******************** + public String computeHMAC( String input ) throws EncryptionException { + try { + Mac hmac = Mac.getInstance("HMacSHA1"); // DISCUSS: Changed to HMacSHA1. MD5 *badly* broken + // SHA1 should really be avoided, but using + // for HMAC-SHA1 is acceptable for now. Plan + // to migrate to SHA-256 or NIST replacement for + // SHA1 in not too distant future. + // DISCUSS: Also not recommended that the HMac key is the same as the one + // used for encryption (namely, Encryptor.MasterKey). If anything it + // would be better to use Encryptor.MasterSalt for the HMac key, or + // perhaps a derived key based on the master salt. (One could use + // KeyDerivationFunction.computeDerivedKey().) + // + byte[] salt = ESAPI.securityConfiguration().getMasterSalt(); + hmac.init( new SecretKeySpec(salt, "HMacSHA1") ); // Was: hmac.init(secretKeySpec) + byte[] inBytes; + try { + inBytes = input.getBytes("UTF-8"); + } catch (UnsupportedEncodingException e) { + logger.warning(Logger.SECURITY_FAILURE, "computeHMAC(): Can't find UTF-8 encoding; using default encoding", e); + inBytes = input.getBytes(); + } + byte[] bytes = hmac.doFinal( inBytes ); + return ESAPI.encoder().encodeForBase64(bytes, false); + } catch (InvalidKeyException ike) { + throw new EncryptionException("Encryption failure", "Must install unlimited strength crypto extension from Sun", ike); + } catch (NoSuchAlgorithmException e) { + throw new EncryptionException("Could not compute HMAC", "Can't find HMacSHA1 algorithm. " + + "Problem computing HMAC for " + input, e ); + } + } +********************/ + + /** + * Log a security warning every Nth time one of the deprecated encrypt or + * decrypt methods are called. ('N' is hard-coded to be 25 by default, but + * may be changed via the system property + * {@code ESAPI.Encryptor.warnEveryNthUse}.) In other words, we nag + * them until the give in and change it. ;-) + * + * @param where The string "encrypt" or "decrypt", corresponding to the + * method that is being logged. + * @param msg The message to log. + */ + private void logWarning(String where, String msg) { + int counter = 0; + if ( where.equals("encrypt") ) { + counter = encryptCounter++; + where = "JavaEncryptor.encrypt(): [count=" + counter +"]"; + } else if ( where.equals("decrypt") ) { + counter = decryptCounter++; + where = "JavaEncryptor.decrypt(): [count=" + counter +"]"; + } else { + where = "JavaEncryptor: Unknown method: "; + } + // We log the very first time (note the use of post-increment on the + // counters) and then every Nth time thereafter. Logging every single + // time is likely to be way too much logging. + if ( (counter % logEveryNthUse) == 0 ) { + logger.warning(Logger.SECURITY_FAILURE, where + msg); + } + } + + private KeyDerivationFunction.PRF_ALGORITHMS getPRF(String name) { + String prfName = null; + if ( name == null ) { + prfName = ESAPI.securityConfiguration().getKDFPseudoRandomFunction(); + } else { + prfName = name; + } + KeyDerivationFunction.PRF_ALGORITHMS prf = KeyDerivationFunction.convertNameToPRF(prfName); + return prf; + } + + private KeyDerivationFunction.PRF_ALGORITHMS getDefaultPRF() { + String prfName = ESAPI.securityConfiguration().getKDFPseudoRandomFunction(); + return getPRF(prfName); + } + + // Private interface to call ESAPI's KDF to get key for encryption or authenticity. + private SecretKey computeDerivedKey(int kdfVersion, KeyDerivationFunction.PRF_ALGORITHMS prf, + SecretKey kdk, int keySize, String purpose) + throws NoSuchAlgorithmException, InvalidKeyException, EncryptionException + { + // These really should be turned into actual runtime checks and an + // IllegalArgumentException should be thrown if they are violated. + // But this should be OK since this is a private method. Also, this method will + // be called quite often so assertions are a big win as they can be disabled or + // enabled at will. + assert prf != null : "Pseudo Random Function for KDF cannot be null"; + assert kdk != null : "Key derivation key cannot be null."; + // We would choose a larger minimum key size, but we want to be + // able to accept DES for legacy encryption needs. NIST says 112-bits is min. If less than that, + // we print warning. + assert keySize >= 56 : "Key has size of " + keySize + ", which is less than absolute minimum of 56-bits."; + assert (keySize % 8) == 0 : "Key size (" + keySize + ") must be a even multiple of 8-bits."; + + // However, this one we want as a runtime check because we don't have this check + // in KeyDerivationFunction.computeDerivedKey() as we want that method + // to be more general. + if ( !( purpose.equals("encryption") || purpose.equals("authenticity") ) ) { + String exMsg = "Programming error in ESAPI?? 'purpose' for computeDerivedKey() must be \"encryption\" or \"authenticity\"."; + throw new EncryptionException(exMsg, exMsg); + } + + KeyDerivationFunction kdf = new KeyDerivationFunction(prf); + if ( kdfVersion != 0 ) { + kdf.setVersion(kdfVersion); + } + return kdf.computeDerivedKey(kdk, keySize, purpose); + } + + // Get all the algorithms we will be using from ESAPI.properties. + private static void setupAlgorithms() { + // setup algorithms + encryptAlgorithm = ESAPI.securityConfiguration().getEncryptionAlgorithm(); + signatureAlgorithm = ESAPI.securityConfiguration().getDigitalSignatureAlgorithm(); + randomAlgorithm = ESAPI.securityConfiguration().getRandomAlgorithm(); + hashAlgorithm = ESAPI.securityConfiguration().getHashAlgorithm(); + hashIterations = ESAPI.securityConfiguration().getHashIterations(); + encoding = ESAPI.securityConfiguration().getCharacterEncoding(); + encryptionKeyLength = ESAPI.securityConfiguration().getEncryptionKeyLength(); + signatureKeyLength = ESAPI.securityConfiguration().getDigitalSignatureKeyLength(); + } + + // Set up signing key pair using the master password and salt. Called (once) + // from the JavaEncryptor CTOR. + private static void initKeyPair(SecureRandom prng) throws NoSuchAlgorithmException { + String sigAlg = signatureAlgorithm.toLowerCase(); + if ( sigAlg.endsWith("withdsa") ) { + // + // Admittedly, this is a kludge. However for Sun JCE, even though + // "SHA1withDSA" is a valid signature algorithm name, if one calls + // KeyPairGenerator kpg = KeyPairGenerator.getInstance("SHA1withDSA"); + // that will throw a NoSuchAlgorithmException with an exception + // message of "SHA1withDSA KeyPairGenerator not available". Since + // SHA1withDSA and DSA keys should be identical, we use "DSA" + // in the case that SHA1withDSA or SHAwithDSA was specified. This is + // all just to make these 2 work as expected. Sigh. (Note: + // this was tested with JDK 1.6.0_21, but likely fails with earlier + // versions of the JDK as well. Haven't experimented with later + // versions.) + // + sigAlg = "DSA"; + } else if ( sigAlg.endsWith("withrsa") ) { + // Ditto for RSA. + sigAlg = "RSA"; + } + KeyPairGenerator keyGen = KeyPairGenerator.getInstance(sigAlg); + keyGen.initialize(signatureKeyLength, prng); + KeyPair pair = keyGen.generateKeyPair(); + privateKey = pair.getPrivate(); + publicKey = pair.getPublic(); + } +} diff --git a/src/main/java/org/owasp/esapi/reference/crypto/ReferenceEncryptedProperties.java b/src/main/java/org/owasp/esapi/reference/crypto/ReferenceEncryptedProperties.java new file mode 100644 index 000000000..1137a5fbc --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/crypto/ReferenceEncryptedProperties.java @@ -0,0 +1,293 @@ +/** + * 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.reference.crypto; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.Reader; +import java.util.Collection; +import java.util.Enumeration; +import java.util.Properties; +import java.util.Set; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.EncryptedProperties; +import org.owasp.esapi.Logger; +import org.owasp.esapi.crypto.CipherText; +import org.owasp.esapi.crypto.PlainText; +import org.owasp.esapi.errors.EncryptionRuntimeException; + +/** + * Reference implementation of the {@code EncryptedProperties} interface. This + * implementation wraps a normal properties file, and creates surrogates for the + * {@code getProperty} and {@code setProperty} methods that perform encryption + * and decryption based on {@code Encryptor}. + *

+ * This implementation differs from {@code DefaultEncryptedProperties} in that + * it actually extends from {@code java.util.Properties} for applications that need an + * instance of that class. In order to do so, the {@code getProperty} and + * {@code setProperty} methods were modified to throw {@code EncryptionRuntimeException} + * instead of {@code EncryptionException}. + * + * @author August Detlefsen (augustd at codemagi dot com) + * CodeMagi, Inc. + * @author kevin.w.wall@gmail.com + * @since October 8, 2010 + * @see org.owasp.esapi.EncryptedProperties + * @see org.owasp.esapi.reference.crypto.DefaultEncryptedProperties + */ +public class ReferenceEncryptedProperties extends java.util.Properties implements EncryptedProperties { + + /** + * serverVersionUID; use format of YYYYMMDD. + */ + private static final long serialVersionUID = 20120718L; + + /** The logger. */ + private final Logger logger = ESAPI.getLogger(this.getClass()); + + private static final String[] GET_ERROR_MESSAGES = new String[]{ + ": failed decoding from base64", + ": failed to deserialize properly", + ": failed to decrypt properly" + }; + + private static final String[] SET_ERROR_MESSAGES = new String[]{ + ": failed to encrypt properly", + ": failed to serialize correctly", + ": failed to base64-encode properly", + ": failed to set base64-encoded value as property. Illegal key name?" + }; + + /** + * Instantiates a new encrypted properties. + */ + public ReferenceEncryptedProperties() { + super(); + } + + public ReferenceEncryptedProperties(Properties defaults) { + super(); + + for (Object oKey : defaults.keySet()) { + String key = (oKey instanceof String) ? (String)oKey : oKey.toString(); + String value = defaults.getProperty(key); + + this.setProperty(key, value); + } + } + + /** + * {@inheritDoc} + * + * @throws EncryptionRuntimeException Thrown if decryption fails. + */ + @Override + public synchronized String getProperty(String key) throws EncryptionRuntimeException { + int progressMark = 0; + try { + String encryptedValue = super.getProperty(key); + + if(encryptedValue==null) + return null; + + progressMark = 0; + byte[] serializedCiphertext = ESAPI.encoder().decodeFromBase64(encryptedValue); + progressMark++; + CipherText restoredCipherText = CipherText.fromPortableSerializedBytes(serializedCiphertext); + progressMark++; + PlainText plaintext = ESAPI.encryptor().decrypt(restoredCipherText); + + return plaintext.toString(); + } catch (Exception e) { + throw new EncryptionRuntimeException("Property retrieval failure", + "Couldn't retrieve encrypted property for property " + key + + GET_ERROR_MESSAGES[progressMark], e); + } + } + + /** + * {@inheritDoc} + * + * @throws EncryptionRuntimeException Thrown if decryption fails. + */ + @Override + public synchronized String getProperty(String key, String defaultValue) throws EncryptionRuntimeException { + String value = getProperty(key); + + if (value == null) return defaultValue; + + return value; + } + + /** + * {@inheritDoc} + * + * @throws EncryptionRuntimeException Thrown if encryption fails. + */ + @Override + public synchronized String setProperty(String key, String value) throws EncryptionRuntimeException { + int progressMark = 0; + try { + if ( key == null ) { + throw new NullPointerException("Property name may not be null."); + } + if ( value == null ) { + throw new NullPointerException("Property value may not be null."); + } + // NOTE: Not backward compatible w/ ESAPI 1.4. + PlainText pt = new PlainText(value); + CipherText ct = ESAPI.encryptor().encrypt(pt); + progressMark++; + byte[] serializedCiphertext = ct.asPortableSerializedByteArray(); + progressMark++; + String b64str = ESAPI.encoder().encodeForBase64(serializedCiphertext, false); + progressMark++; + return (String)super.put(key, b64str); + } catch (Exception e) { + throw new EncryptionRuntimeException("Property setting failure", + "Couldn't set encrypted property " + key + + SET_ERROR_MESSAGES[progressMark], e); + } + } + + /** + * {@inheritDoc} + * @throws IOException Thrown if input stream invalid or does not + * correspond to Java properties file format. + */ + @Override + public void load(InputStream in) throws IOException { + super.load(in); + logger.trace(Logger.SECURITY_SUCCESS, "Encrypted properties loaded successfully"); + } + + /** + * {@inheritDoc} + * + * For JDK 1.5 compatibility, this method has been overridden convert the Reader + * into an InputStream and call the superclass constructor. + * + * @throws IOException Thrown if {@code Reader} input stream invalid or does not + * correspond to Java properties file format. + */ + public void load(Reader in) throws IOException { + + if (in == null) return; + + //read from the reader into a StringBuffer + char[] cbuf = new char[65536]; + BufferedReader buff = new BufferedReader(in); + StringBuilder contents = new StringBuilder(); + + int read_this_time = 0; + while (read_this_time != -1) { + read_this_time = buff.read(cbuf, 0, 65536); + if (read_this_time > 0) contents.append(cbuf, 0, read_this_time); + } + + //create a new InputStream from the StringBuffer + InputStream is = new ByteArrayInputStream(contents.toString().getBytes()); + + super.load(is); + logger.trace(Logger.SECURITY_SUCCESS, "Encrypted properties loaded successfully"); + } + + /** + * This method has been overridden to throw an {@code UnsupportedOperationException} + */ + @Override + public void list(PrintStream out) { + throw new UnsupportedOperationException("This method has been removed for security."); + } + + /** + * This method has been overridden to throw an {@code UnsupportedOperationException} + */ + @Override + public void list(PrintWriter out) { + throw new UnsupportedOperationException("This method has been removed for security."); + } + + /** + * This method has been overridden to throw an {@code UnsupportedOperationException} + */ + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public Collection values() { + throw new UnsupportedOperationException("This method has been removed for security."); + } + + /** + * This method has been overridden to throw an {@code UnsupportedOperationException} + */ + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public Set entrySet() { + throw new UnsupportedOperationException("This method has been removed for security."); + } + + /** + * This method has been overridden to throw an {@code UnsupportedOperationException} + */ + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public Enumeration elements() { + throw new UnsupportedOperationException("This method has been removed for security."); + } + + /** + * This method has been overridden to only accept Strings for key and value, and to encrypt + * those Strings before storing them. Outside classes should always use {@code setProperty} + * to add values to the Properties map. If an outside class does erroneously call this method + * with non-String parameters an {@code IllegalArgumentException} will be thrown. + * + * @param key A String key to add + * @param value A String value to add + * @return The old value associated with the specified key, or {@code null} + * if the key did not exist. + */ + @Override + public synchronized Object put(Object key, Object value) { + //if java.util.Properties is calling this method, just forward to the implementation in + //the superclass (java.util.Hashtable) + Throwable t = new Throwable(); + for (StackTraceElement trace : t.getStackTrace()) { + if ("java.util.Properties".equals(trace.getClassName()) ) return super.put(key, value); + } + + //otherwise, if both arguments are Strings, encrypt and store them + if (key instanceof String && value instanceof String) return setProperty((String)key, (String)value); + + //other Object types are not allowed + throw new IllegalArgumentException("This method has been overridden to only accept Strings for key and value."); + } + + /** + * This method has been overridden to not print out the keys and values stored in this properties file. + * + * @return The minimal String representation of this class, as per java.lang.Object. + */ + @Override + public String toString() { + return getClass().getName() + "@" + Integer.toHexString(hashCode()); + } + +} diff --git a/src/main/java/org/owasp/esapi/reference/crypto/package.html b/src/main/java/org/owasp/esapi/reference/crypto/package.html new file mode 100644 index 000000000..91140701c --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/crypto/package.html @@ -0,0 +1,10 @@ + + + + + + +This package contains the reference implementation for some of +the ESAPI cryptography-related classes used throughout ESAPI. + + \ No newline at end of file diff --git a/src/main/java/org/owasp/esapi/reference/package.html b/src/main/java/org/owasp/esapi/reference/package.html new file mode 100644 index 000000000..e1fe0b048 --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/package.html @@ -0,0 +1,16 @@ + + + + + + + +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. + + + diff --git a/src/main/java/org/owasp/esapi/reference/validation/BaseValidationRule.java b/src/main/java/org/owasp/esapi/reference/validation/BaseValidationRule.java new file mode 100644 index 000000000..b9251198c --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/validation/BaseValidationRule.java @@ -0,0 +1,202 @@ +/** + * 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.reference.validation; + + +import java.util.HashSet; +import java.util.Set; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Encoder; +import org.owasp.esapi.ValidationErrorList; +import org.owasp.esapi.ValidationRule; +import org.owasp.esapi.errors.ValidationException; + + +/** + * A ValidationRule performs syntax and possibly semantic validation of a single + * piece of data from an untrusted source. + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @since June 1, 2007 + * @see org.owasp.esapi.Validator + */ +public abstract class BaseValidationRule implements ValidationRule { + + private String typeName = null; + protected boolean allowNull = false; + protected Encoder encoder = null; + + private BaseValidationRule() { + // prevent use of no-arg constructor + } + + public BaseValidationRule( String typeName ) { + this(); + setEncoder( ESAPI.encoder() ); + setTypeName( typeName ); + } + + public BaseValidationRule( String typeName, Encoder encoder ) { + this(); + setEncoder( encoder ); + setTypeName( typeName ); + } + + /** + * {@inheritDoc} + */ + public void setAllowNull( boolean flag ) { + allowNull = flag; + } + + /** + * {@inheritDoc} + */ + public String getTypeName() { + return typeName; + } + + /** + * {@inheritDoc} + */ + public final void setTypeName( String typeName ) { + this.typeName = typeName; + } + + /** + * {@inheritDoc} + */ + public final void setEncoder( Encoder encoder ) { + this.encoder = encoder; + } + + /** + * {@inheritDoc} + */ + public void assertValid( String context, String input ) throws ValidationException { + getValid( context, input ); + } + + /** + * {@inheritDoc} + */ + public Object getValid( String context, String input, ValidationErrorList errorList ) throws ValidationException { + Object valid = null; + try { + valid = getValid( context, input ); + } catch (ValidationException e) { + if( errorList == null) { + throw e; + } else { + errorList.addError(context, e); + } + } + return valid; + } + + /** + * {@inheritDoc} + */ + public Object getSafe( String context, String input ) { + Object valid = null; + try { + valid = getValid( context, input ); + } catch ( ValidationException e ) { + return sanitize( context, input ); + } + return valid; + } + + /** + * The method is similar to ValidationRuile.getSafe except that it returns a + * harmless object that may or may not have any similarity to the original + * input (in some cases you may not care). In most cases this should be the + * same as the getSafe method only instead of throwing an exception, return + * some default value. + * + * @param context + * @param input + * @return a parsed version of the input or a default value. + */ + protected abstract Object sanitize( String context, String input ); + + /** + * {@inheritDoc} + */ + public boolean isValid( String context, String input ) { + boolean valid = false; + try { + getValid( context, input ); + valid = true; + } catch( Exception e ) { + valid = false; + } + + return valid; + } + + /** + * {@inheritDoc} + */ + public String whitelist( String input, char[] whitelist) { + return whitelist(input, charArrayToSet(whitelist)); + } + + /** + * Removes characters that aren't in the whitelist from the input String. + * O(input.length) whitelist performance + * @param input String to be sanitized + * @param whitelist allowed characters + * @return input stripped of all chars that aren't in the whitelist + */ + public String whitelist( String input, Set whitelist) { + StringBuilder stripped = new StringBuilder(); + for (int i = 0; i < input.length(); i++) { + char c = input.charAt(i); + if (whitelist.contains(c)) { + stripped.append(c); + } + } + return stripped.toString(); + } + + // CHECKME should be moved to some utility class (Would potentially be used by new EncoderConstants class) + // Is there a standard way to convert an array of primitives to a Collection + /** + * Convert an array of characters to a {@code Set} (so duplicates + * are removed). + * @param array The character array. + * @return A {@code Set} of the unique characters from {@code array} + * is returned. + */ + public static Set charArrayToSet(char[] array) { + Set toReturn = new HashSet(array.length); + for (char c : array) { + toReturn.add(c); + } + return toReturn; + } + + public boolean isAllowNull() { + return allowNull; + } + + public Encoder getEncoder() { + return encoder; + } +} diff --git a/src/main/java/org/owasp/esapi/reference/validation/CreditCardValidationRule.java b/src/main/java/org/owasp/esapi/reference/validation/CreditCardValidationRule.java new file mode 100644 index 000000000..1e82c0e9a --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/validation/CreditCardValidationRule.java @@ -0,0 +1,165 @@ +/** + * 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.reference.validation; + +import java.util.regex.Pattern; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Encoder; +import org.owasp.esapi.EncoderConstants; +import org.owasp.esapi.StringUtilities; +import org.owasp.esapi.errors.ValidationException; + +/** + * A validator performs syntax and possibly semantic validation of Credit Card + * String from an untrusted source. + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @since June 1, 2007 + * @see org.owasp.esapi.Validator + */ +public class CreditCardValidationRule extends BaseValidationRule { + private int maxCardLength = 19; + + /** + * Key used to pull out encoder in configuration. Prefixed with "Validator." + */ + protected static final String CREDIT_CARD_VALIDATOR_KEY = "CreditCard"; + + private StringValidationRule ccrule = null; + + /** + * Creates a CreditCardValidator using the rule found in security configuration + * @param typeName a description of the type of card being validated + * @param encoder + */ + public CreditCardValidationRule( String typeName, Encoder encoder ) { + super( typeName, encoder ); + ccrule = readDefaultCreditCardRule(); + } + + public CreditCardValidationRule( String typeName, Encoder encoder, StringValidationRule validationRule ) { + super( typeName, encoder ); + ccrule = validationRule; + } + + private StringValidationRule readDefaultCreditCardRule() { + Pattern p = ESAPI.securityConfiguration().getValidationPattern( CREDIT_CARD_VALIDATOR_KEY ); + StringValidationRule ccr = new StringValidationRule( "ccrule", encoder, p.pattern() ); + ccr.setMaximumLength(getMaxCardLength()); + ccr.setAllowNull( false ); + return ccr; + } + + /** + * {@inheritDoc} + */ + public String getValid( String context, String input ) throws ValidationException { + // CHECKME should this allow empty Strings? " " us IsBlank instead? + if ( StringUtilities.isEmpty(input) ) { + if (allowNull) { + return null; + } + throw new ValidationException( context + ": Input credit card required", "Input credit card required: context=" + context + ", input=" + input, context ); + } + + String canonical = ccrule.getValid( context, input ); + + if( ! validCreditCardFormat(canonical)) { + throw new ValidationException( context + ": Invalid credit card input", "Invalid credit card input: context=" + context, context ); + } + + return canonical; + } + + /** + * Performs additional validation on the card nummber. + * This implementation performs Luhn algorithm checking + * @param ccNum number to be validated + * @return true if the ccNum passes the Luhn Algorithm + */ + protected boolean validCreditCardFormat(String ccNum) { + + StringBuilder digitsOnly = new StringBuilder(); + char c; + for (int i = 0; i < ccNum.length(); i++) { + c = ccNum.charAt(i); + if (Character.isDigit(c)) { + digitsOnly.append(c); + } + } + + int sum = 0; + int digit = 0; + int addend = 0; + boolean timesTwo = false; + + for (int i = digitsOnly.length() - 1; i >= 0; i--) { + // guaranteed to be an int + digit = Integer.valueOf(digitsOnly.substring(i, i + 1)); + if (timesTwo) { + addend = digit * 2; + if (addend > 9) { + addend -= 9; + } + } else { + addend = digit; + } + sum += addend; + timesTwo = !timesTwo; + } + + return sum % 10 == 0; + + } + + /** + * {@inheritDoc} + */ + @Override + public String sanitize( String context, String input ) { + return whitelist( input, EncoderConstants.CHAR_DIGITS ); + } + + /** + * @param ccrule the ccrule to set + */ + public void setStringValidatorRule(StringValidationRule ccrule) { + this.ccrule = ccrule; + } + + /** + * @return the ccrule + */ + public StringValidationRule getStringValidatorRule() { + return ccrule; + } + + /** + * @param maxCardLength the maxCardLength to set + */ + public void setMaxCardLength(int maxCardLength) { + this.maxCardLength = maxCardLength; + } + + /** + * @return the maxCardLength + */ + public int getMaxCardLength() { + return maxCardLength; + } +} diff --git a/src/main/java/org/owasp/esapi/reference/validation/DateValidationRule.java b/src/main/java/org/owasp/esapi/reference/validation/DateValidationRule.java new file mode 100644 index 000000000..340800409 --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/validation/DateValidationRule.java @@ -0,0 +1,123 @@ +/** + * 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.reference.validation; + +import java.text.DateFormat; +import java.util.Date; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Encoder; +import org.owasp.esapi.StringUtilities; +import org.owasp.esapi.ValidationErrorList; +import org.owasp.esapi.errors.ValidationException; + +/** + * A validator performs syntax and possibly semantic validation of a single + * piece of data from an untrusted source. + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @since June 1, 2007 + * @see org.owasp.esapi.Validator + */ +public class DateValidationRule extends BaseValidationRule { + private DateFormat format = DateFormat.getDateInstance(); + + public DateValidationRule( String typeName, Encoder encoder, DateFormat newFormat ) { + super( typeName, encoder ); + setDateFormat( newFormat ); + } + + public final void setDateFormat( DateFormat newFormat ) { + if (newFormat == null) { + throw new IllegalArgumentException("DateValidationRule.setDateFormat requires a non-null DateFormat"); + } + // CHECKME fail fast? +/* + try { + newFormat.parse(new Date()); + } catch (ParseException e) { + throw new IllegalArgumentException(e); + } +*/ + this.format = newFormat; + this.format.setLenient( ESAPI.securityConfiguration().getLenientDatesAccepted() ); + } + + /** + * {@inheritDoc} + */ + public Date getValid( String context, String input ) throws ValidationException { + return safelyParse(context, input, false); + } + + /** + * {@inheritDoc} + */ + @Override + public Date sanitize( String context, String input ) { + return sanitize(context, input, null); + } + + /** + * Same as sanitize(String, String) except it returns any ValidationException generated in the provided errorList. + * + * @param errorList The error list to add any ValidationException to. + * @return The valid sanitized Date, or Date(0) if the supplied input was not a valid date. + */ + public Date sanitize( String context, String input, ValidationErrorList errorList ) { + Date date = new Date(0); + try { + date = safelyParse(context, input, true); + } catch (ValidationException e) { + if (errorList != null) { + errorList.addError(context, e); + } + } + return date; + } + + private Date safelyParse(String context, String input, boolean sanitize) + throws ValidationException { + // CHECKME should this allow empty Strings? " " use IsBlank instead? + if (StringUtilities.isEmpty(input)) { + if (allowNull) { + return null; + } + throw new ValidationException(context + ": Input date required", + "Input date required: context=" + context + ", input=" + + input, context); + } + + String canonical = encoder.canonicalize(input); + try { + Date rval = format.parse(canonical); + if (sanitize) { + String cycled = format.format(rval); + if (!cycled.equals(canonical)) { + throw new Exception("Parameter date is not a clean translation between String and Date contexts. Check input for additional characters"); + } + } + return rval; + } catch (Exception e) { + throw new ValidationException(context + + ": Invalid date must follow the " + + format.getNumberFormat() + " format", + "Invalid date: context=" + context + ", format=" + format + + ", input=" + input, e, context); + } + } +} diff --git a/src/main/java/org/owasp/esapi/reference/validation/HTMLValidationRule.java b/src/main/java/org/owasp/esapi/reference/validation/HTMLValidationRule.java new file mode 100644 index 000000000..87de340d5 --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/validation/HTMLValidationRule.java @@ -0,0 +1,262 @@ +/** + * 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.reference.validation; + + + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.List; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Encoder; +import org.owasp.esapi.Logger; +import org.owasp.esapi.SecurityConfiguration; +import org.owasp.esapi.StringUtilities; +import org.owasp.esapi.errors.ConfigurationException; +import org.owasp.esapi.errors.ValidationException; +import org.owasp.esapi.PropNames.DefaultSearchPath; +import static org.owasp.esapi.PropNames.VALIDATOR_HTML_VALIDATION_ACTION; +import static org.owasp.esapi.PropNames.VALIDATOR_HTML_VALIDATION_CONFIGURATION_FILE; + +import org.owasp.validator.html.AntiSamy; +import org.owasp.validator.html.CleanResults; +import org.owasp.validator.html.Policy; +import org.owasp.validator.html.PolicyException; +import org.owasp.validator.html.ScanException; + + +/** + * A validator performs syntax and possibly semantic validation of a single + * piece of data from an untrusted source. + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @since June 1, 2007 + * @see org.owasp.esapi.Validator + */ +public class HTMLValidationRule extends StringValidationRule { + + /** OWASP AntiSamy markup verification policy */ + private static Policy antiSamyPolicy = null; + private static final Logger LOGGER = ESAPI.getLogger( "HTMLValidationRule" ); + private static final String ANTISAMYPOLICY_FILENAME = "antisamy-esapi.xml"; + + /*package */ static InputStream getResourceStreamFromClassLoader(String contextDescription, ClassLoader classLoader, String fileName, List searchPaths) { + InputStream result = null; + + for (String searchPath: searchPaths) { + result = classLoader.getResourceAsStream(searchPath + fileName); + + if (result != null) { + LOGGER.info(Logger.EVENT_SUCCESS, "SUCCESSFULLY LOADED " + fileName + " via the CLASSPATH from '" + + searchPath + "' using " + contextDescription + "!"); + break; + } + } + + return result; + } + + /*package */ static InputStream getResourceStreamFromClasspath(String fileName) { + LOGGER.info(Logger.EVENT_FAILURE, "Loading " + fileName + " from classpaths"); + + InputStream resourceStream = null; + + List orderedSearchPaths = Arrays.asList(DefaultSearchPath.ROOT.value(), + DefaultSearchPath.RESOURCE_DIRECTORY.value(), + DefaultSearchPath.DOT_ESAPI.value(), + DefaultSearchPath.ESAPI.value(), + DefaultSearchPath.RESOURCES.value(), + DefaultSearchPath.SRC_MAIN_RESOURCES.value()); + + resourceStream = getResourceStreamFromClassLoader("current thread context class loader", Thread.currentThread().getContextClassLoader(), fileName, orderedSearchPaths); + + //I'm lazy. Using ternary for shorthand "if null then do next thing" Harder to read, sorry + resourceStream = resourceStream != null ? resourceStream : getResourceStreamFromClassLoader("system class loader", ClassLoader.getSystemClassLoader(), fileName, orderedSearchPaths); + resourceStream = resourceStream != null ? resourceStream : getResourceStreamFromClassLoader("class loader for DefaultSecurityConfiguration class", ESAPI.securityConfiguration().getClass().getClassLoader(), fileName, orderedSearchPaths); + + return resourceStream; + } + + /*package */ static Policy loadAntisamyPolicy(String antisamyPolicyFilename) throws IOException, PolicyException { + InputStream resourceStream = null; + SecurityConfiguration secCfg = ESAPI.securityConfiguration(); + + //Rather than catching the IOException from the resource stream, let's ask if the file exists to give this a best-case resolution. + //This helps with the IOException handling too. If the file is there and we get an IOException from the SecurityConfiguration, then the file is there and something else is wrong (FAIL -- don't try the other path) + File file = secCfg.getResourceFile(antisamyPolicyFilename); + + resourceStream = file == null ? getResourceStreamFromClasspath(antisamyPolicyFilename) : secCfg.getResourceStream(antisamyPolicyFilename); + return resourceStream == null ? null : Policy.getInstance(resourceStream); + } + + /*package */ static String resolveAntisamyFilename() { + String antisamyPolicyFilename = ANTISAMYPOLICY_FILENAME; + try { + antisamyPolicyFilename = ESAPI.securityConfiguration().getStringProp( VALIDATOR_HTML_VALIDATION_CONFIGURATION_FILE ); + } catch (ConfigurationException cex) { + + LOGGER.info(Logger.EVENT_FAILURE, "ESAPI property " + + VALIDATOR_HTML_VALIDATION_CONFIGURATION_FILE + + " not set, using default value: " + ANTISAMYPOLICY_FILENAME); + } + return antisamyPolicyFilename; + } + + /*package */ static void configureInstance() { + String antisamyPolicyFilename = resolveAntisamyFilename(); + + try { + antiSamyPolicy = loadAntisamyPolicy(antisamyPolicyFilename); + } catch (IOException ioe) { + //Thrown if file is found by SecurityConfiguration, but a stream cannot be generated. + throw new ConfigurationException("Failed to load file from SecurityConfiguration context: " + antisamyPolicyFilename, ioe); + } catch (PolicyException e) { + //Thrown if the resource stream was created, but the contents of the file are not compatible with antisamy expectations. + throw new ConfigurationException("Couldn't parse " + antisamyPolicyFilename, e); + } + + if (antiSamyPolicy == null) { + throw new ConfigurationException("Couldn't find " + antisamyPolicyFilename); + } + + } + + static { + configureInstance(); + } + + public HTMLValidationRule( String typeName ) { + super( typeName ); + } + + public HTMLValidationRule( String typeName, Encoder encoder ) { + super( typeName, encoder ); + } + + public HTMLValidationRule( String typeName, Encoder encoder, String whitelistPattern ) { + super( typeName, encoder, whitelistPattern ); + } + + /** + * {@inheritDoc} + */ + @Override + public String getValid( String context, String input ) throws ValidationException { + return invokeAntiSamy( context, input ); + } + + /** + * {@inheritDoc} + */ + @Override + public String sanitize( String context, String input ) { + String safe = ""; + try { + safe = invokeAntiSamy( context, input ); + } catch( ValidationException e ) { + // just return safe + } + return safe; + } + + /** + * Check whether we want the legacy behavior ("clean") or the presumably intended + * behavior of "throw" for how to treat unsafe HTML input when AntiSamy is invoked. + * This admittedly is an UGLY hack to ensure that issue 509 and its corresponding + * fix in PR #510 does not break existing developer's existing code. Full + * details are described in GitHub issue 521. + * + * Checks new ESAPI property "Validator.HtmlValidationAction". A value of "clean" + * means to revert to legacy behavior. A value of "throw" means to use the new + * behavior as implemented in GitHub issue 509. + * + * @return false - If "Validator.HtmlValidationAction" is set to "throw". Otherwise {@code true}. + * @since 2.2.1.0 + */ + private boolean legacyHtmlValidation() { + boolean legacy = true; // Make legacy support the default behavior for backward compatibility. + String propValue = "clean"; // For legacy support. + try { + // DISCUSS: + // Hindsight: maybe we should have getBooleanProp(), getStringProp(), + // getIntProp() methods that take a default arg as well? + // At least for ESAPI 3.x. + propValue = ESAPI.securityConfiguration().getStringProp( VALIDATOR_HTML_VALIDATION_ACTION ); + switch ( propValue.toLowerCase() ) { + case "throw": + legacy = false; // New, presumably correct behavior, as addressed by GitHub issue 509 + break; + case "clean": + legacy = true; // Give the caller that legacy behavior of sanitizing. + break; + default: + LOGGER.warning(Logger.EVENT_FAILURE, "ESAPI property " + + VALIDATOR_HTML_VALIDATION_ACTION + + " was set to \"" + propValue + "\". Must be set to either \"clean\"" + + " (the default for legacy support) or \"throw\"; assuming \"clean\" for legacy behavior."); + legacy = true; + break; + } + } catch( ConfigurationException cex ) { + // OPEN ISSUE: Should we log this? I think so. Convince me otherwise. But maybe + // we should only log it once or every Nth time?? + LOGGER.warning(Logger.EVENT_FAILURE, "ESAPI property " + + VALIDATOR_HTML_VALIDATION_ACTION + + " must be set to either \"clean\" (the default for legacy support) or \"throw\"; assuming \"clean\"", + cex); + } + + return legacy; + } + + private String invokeAntiSamy( String context, String input ) throws ValidationException { + // CHECKME should this allow empty Strings? " " use IsBlank instead? + if ( StringUtilities.isEmpty(input) ) { + if (allowNull) { + return null; + } + throw new ValidationException( context + " is required", "AntiSamy validation error: context=" + context + ", input=" + input, context ); + } + + String canonical = super.getValid( context, input ); + + try { + AntiSamy as = new AntiSamy(); + CleanResults test = as.scan(canonical, antiSamyPolicy); // Uses AntiSamy.DOM scanner. + + List errors = test.getErrorMessages(); + if ( !errors.isEmpty() ) { + if ( legacyHtmlValidation() ) { // See GitHub issues 509 and 521 + LOGGER.info(Logger.SECURITY_FAILURE, "Cleaned up invalid HTML input: " + errors ); + } else { + throw new ValidationException( context + ": Invalid HTML input", "Invalid HTML input does not follow rules in antisamy-esapi.xml: context=" + context + " errors=" + errors.toString()); + } + } + + return test.getCleanHTML().trim(); + + } catch (ScanException e) { + throw new ValidationException( context + ": Invalid HTML input", "Invalid HTML input: context=" + context + " error=" + e.getMessage(), e, context ); + } catch (PolicyException e) { + throw new ValidationException( context + ": Invalid HTML input", "Invalid HTML input does not follow rules in antisamy-esapi.xml: context=" + context + " error=" + e.getMessage(), e, context ); + } + } +} + diff --git a/src/main/java/org/owasp/esapi/reference/validation/IntegerValidationRule.java b/src/main/java/org/owasp/esapi/reference/validation/IntegerValidationRule.java new file mode 100644 index 000000000..3137781e3 --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/validation/IntegerValidationRule.java @@ -0,0 +1,95 @@ +/** + * 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.reference.validation; + +import org.owasp.esapi.Encoder; +import org.owasp.esapi.StringUtilities; +import org.owasp.esapi.errors.ValidationException; + + +/** + * A validator performs syntax and possibly semantic validation of a single + * piece of data from an untrusted source. + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @since June 1, 2007 + * @see org.owasp.esapi.Validator + */ +public class IntegerValidationRule extends BaseValidationRule { + + private int minValue = Integer.MIN_VALUE; + private int maxValue = Integer.MAX_VALUE; + + public IntegerValidationRule( String typeName, Encoder encoder ) { + super( typeName, encoder ); + } + + public IntegerValidationRule( String typeName, Encoder encoder, int minValue, int maxValue ) { + super( typeName, encoder ); + this.minValue = minValue; + this.maxValue = maxValue; + } + + public Integer getValid( String context, String input ) throws ValidationException { + return safelyParse(context, input); + } + + private Integer safelyParse(String context, String input) throws ValidationException { + // do not allow empty Strings such as " " - so trim to ensure + // isEmpty catches " " + if (input != null) input = input.trim(); + + if ( StringUtilities.isEmpty(input) ) { + if (allowNull) { + return null; + } + throw new ValidationException( context + ": Input number required", "Input number required: context=" + context + ", input=" + input, context ); + } + + // canonicalize + String canonical = encoder.canonicalize( input ); + + if (minValue > maxValue) { + throw new ValidationException( context + ": Invalid number input: context", "Validation parameter error for number: maxValue ( " + maxValue + ") must be greater than minValue ( " + minValue + ") for " + context, context ); + } + + // validate min and max + try { + int i = Integer.valueOf(canonical); + if (i < minValue) { + throw new ValidationException( "Invalid number input must be between " + minValue + " and " + maxValue + ": context=" + context, "Invalid number input must be between " + minValue + " and " + maxValue + ": context=" + context + ", input=" + input, context ); + } + if (i > maxValue) { + throw new ValidationException( "Invalid number input must be between " + minValue + " and " + maxValue + ": context=" + context, "Invalid number input must be between " + minValue + " and " + maxValue + ": context=" + context + ", input=" + input, context ); + } + return i; + } catch (NumberFormatException e) { + throw new ValidationException( context + ": Invalid number input", "Invalid number input format: context=" + context + ", input=" + input, e, context); + } + } + + @Override + public Integer sanitize( String context, String input ) { + Integer toReturn = Integer.valueOf( 0 ); + try { + toReturn = safelyParse(context, input); + } catch (ValidationException e ) { + // do nothing + } + return toReturn; + } +} \ No newline at end of file diff --git a/src/main/java/org/owasp/esapi/reference/validation/NumberValidationRule.java b/src/main/java/org/owasp/esapi/reference/validation/NumberValidationRule.java new file mode 100644 index 000000000..c19f2ab98 --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/validation/NumberValidationRule.java @@ -0,0 +1,146 @@ +/** + * 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.reference.validation; + +import java.math.BigDecimal; + +import org.owasp.esapi.Encoder; +import org.owasp.esapi.StringUtilities; +import org.owasp.esapi.errors.ValidationException; + + +/** + * A validator performs syntax and possibly semantic validation of a single + * piece of data from an untrusted source. + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @since June 1, 2007 + * @see org.owasp.esapi.Validator + */ +public class NumberValidationRule extends BaseValidationRule { + + private double minValue = Double.NEGATIVE_INFINITY; + private double maxValue = Double.POSITIVE_INFINITY; + + public NumberValidationRule( String typeName, Encoder encoder ) { + super( typeName, encoder ); + } + + public NumberValidationRule( String typeName, Encoder encoder, double minValue, double maxValue ) { + super( typeName, encoder ); + this.minValue = minValue; + this.maxValue = maxValue; + } + + /** + * {@inheritDoc} + */ + public Double getValid( String context, String input ) throws ValidationException { + return safelyParse(context, input); + } + + /** + * {@inheritDoc} + */ + @Override + public Double sanitize( String context, String input ) { + Double toReturn = Double.valueOf(0); + try { + toReturn = safelyParse(context, input); + } catch (ValidationException e) { + // do nothing + } + return toReturn; + } + // + // These statics needed to detect double parsing DOS bug in Java + // + private static BigDecimal bigBad; + private static BigDecimal smallBad; + + static { + + BigDecimal one = new BigDecimal(1); + BigDecimal two = new BigDecimal(2); + + BigDecimal tiny = one.divide(two.pow(1022)); + + // 2^(-1022) ­ 2^(-1076) + bigBad = tiny.subtract(one.divide(two.pow(1076))); + //2^(-1022) ­ 2^(-1075) + smallBad = tiny.subtract(one.divide(two.pow(1075))); + } + + private Double safelyParse(String context, String input) throws ValidationException { + + // CHECKME should this allow empty Strings? " " us IsBlank instead? + if ( StringUtilities.isEmpty(input) ) { + if (allowNull) { + return null; + } + throw new ValidationException( context + ": Input number required", "Input number required: context=" + context + ", input=" + input, context ); + } + + // canonicalize + String canonical = encoder.canonicalize( input ); + + //if MinValue is greater than maxValue then programmer is likely calling this wrong + if (minValue > maxValue) { + throw new ValidationException( context + ": Invalid number input: context", "Validation parameter error for number: maxValue ( " + maxValue + ") must be greater than minValue ( " + minValue + ") for " + context, context ); + } + + //convert to BigDecimal so we can safely parse dangerous numbers to + //check if the number may DOS the double parser + BigDecimal bd; + try { + bd = new BigDecimal(canonical); + } catch (NumberFormatException e) { + throw new ValidationException( context + ": Invalid number input", "Invalid number input format: context=" + context + ", input=" + input, e, context); + } + + // Thanks to Brian Chess for this suggestion + // Check if string input is in the "dangerous" double parsing range + if (bd.compareTo(smallBad) >= 0 && bd.compareTo(bigBad) <= 0) { + // if you get here you know you're looking at a bad value. The final + // value for any double in this range is supposed to be the following safe # + return new Double("2.2250738585072014E-308"); + } + + // the number is safe to parseDouble + Double d; + // validate min and max + try { + d = Double.valueOf(Double.parseDouble( canonical )); + } catch (NumberFormatException e) { + throw new ValidationException( context + ": Invalid number input", "Invalid number input format: context=" + context + ", input=" + input, e, context); + } + + if (d.isInfinite()) { + throw new ValidationException( "Invalid number input: context=" + context, "Invalid double input is infinite: context=" + context + ", input=" + input, context ); + } + if (d.isNaN()) { + throw new ValidationException( "Invalid number input: context=" + context, "Invalid double input is not a number: context=" + context + ", input=" + input, context ); + } + if (d.doubleValue() < minValue) { + throw new ValidationException( "Invalid number input must be between " + minValue + " and " + maxValue + ": context=" + context, "Invalid number input must be between " + minValue + " and " + maxValue + ": context=" + context + ", input=" + input, context ); + } + if (d.doubleValue() > maxValue) { + throw new ValidationException( "Invalid number input must be between " + minValue + " and " + maxValue + ": context=" + context, "Invalid number input must be between " + minValue + " and " + maxValue + ": context=" + context + ", input=" + input, context ); + } + return d; + } +} diff --git a/src/main/java/org/owasp/esapi/reference/validation/StringValidationRule.java b/src/main/java/org/owasp/esapi/reference/validation/StringValidationRule.java new file mode 100644 index 000000000..740db8c7d --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/validation/StringValidationRule.java @@ -0,0 +1,302 @@ +/** + * 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.reference.validation; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Encoder; +import org.owasp.esapi.EncoderConstants; +import org.owasp.esapi.Logger; +import org.owasp.esapi.StringUtilities; +import org.owasp.esapi.errors.ValidationException; +import org.owasp.esapi.util.NullSafe; + + +/** + * A validator performs syntax and possibly semantic validation of a single + * piece of data from an untrusted source. + * + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @since June 1, 2007 + * @see org.owasp.esapi.Validator + * + * http://en.wikipedia.org/wiki/Whitelist + */ +public class StringValidationRule extends BaseValidationRule { + private static final Logger LOGGER = ESAPI.getLogger(StringValidationRule.class); + protected List whitelistPatterns = new ArrayList(); + protected List blacklistPatterns = new ArrayList(); + protected int minLength = 0; + protected int maxLength = Integer.MAX_VALUE; + private boolean canonicalizeInput = true; + + public StringValidationRule( String typeName ) { + super( typeName ); + } + + public StringValidationRule( String typeName, Encoder encoder ) { + super( typeName, encoder ); + } + + public StringValidationRule( String typeName, Encoder encoder, String whitelistPattern ) { + super( typeName, encoder ); + addWhitelistPattern( whitelistPattern ); + } + + /** + * @throws IllegalArgumentException if pattern is null + */ + public void addWhitelistPattern( String pattern ) { + if (pattern == null) { + throw new IllegalArgumentException("Pattern cannot be null"); + } + try { + whitelistPatterns.add( Pattern.compile( pattern ) ); + } catch( PatternSyntaxException e ) { + throw new IllegalArgumentException( "Validation misconfiguration, problem with specified pattern: " + pattern, e ); + } + } + + /** + * @throws IllegalArgumentException if p is null + */ + public void addWhitelistPattern( Pattern p ) { + if (p == null) { + throw new IllegalArgumentException("Pattern cannot be null"); + } + whitelistPatterns.add( p ); + } + + /** + * @throws IllegalArgumentException if pattern is null + */ + public void addBlacklistPattern( String pattern ) { + if (pattern == null) { + throw new IllegalArgumentException("Pattern cannot be null"); + } + try { + blacklistPatterns.add( Pattern.compile( pattern ) ); + } catch( PatternSyntaxException e ) { + throw new IllegalArgumentException( "Validation misconfiguration, problem with specified pattern: " + pattern, e ); + } + } + + /** + * @throws IllegalArgumentException if p is null + */ + public void addBlacklistPattern( Pattern p ) { + if (p == null) { + throw new IllegalArgumentException("Pattern cannot be null"); + } + blacklistPatterns.add( p ); + } + + public void setMinimumLength( int length ) { + minLength = length; + } + + + public void setMaximumLength( int length ) { + maxLength = length; + } + + public void setCanonicalize(boolean canonicalize) { + this.canonicalizeInput = canonicalize; + } + + /** + * checks input against whitelists. + * @param context The context to include in exception messages + * @param input the input to check + * @param orig A origional input to include in exception + * messages. This is not included if it is the same as + * input. + * @return input upon a successful check + * @throws ValidationException if the check fails. + */ + private String checkWhitelist(String context, String input, String orig) throws ValidationException + { + // check whitelist patterns + for (Pattern p : whitelistPatterns) { + if ( !p.matcher(input).matches() ) { + throw new ValidationException( context + ": Invalid input. Please conform to regex " + p.pattern() + ( maxLength == Integer.MAX_VALUE ? "" : " with a maximum length of " + maxLength ), "Invalid input: context=" + context + ", type(" + getTypeName() + ")=" + p.pattern() + ", input=" + input + (NullSafe.equals(orig,input) ? "" : ", orig=" + orig), context ); + } + } + + return input; + } + + /** + * checks input against whitelists. + * @param context The context to include in exception messages + * @param input the input to check + * @return input upon a successful check + * @throws ValidationException if the check fails. + */ + private String checkWhitelist(String context, String input) throws ValidationException + { + return checkWhitelist(context, input, input); + } + + /** + * checks input against blacklists. + * @param context The context to include in exception messages + * @param input the input to check + * @param orig A origional input to include in exception + * messages. This is not included if it is the same as + * input. + * @return input upon a successful check + * @throws ValidationException if the check fails. + */ + private String checkBlacklist(String context, String input, String orig) throws ValidationException + { + // check blacklist patterns + for (Pattern p : blacklistPatterns) { + if ( p.matcher(input).matches() ) { + throw new ValidationException( context + ": Invalid input. Dangerous input matching " + p.pattern() + " detected.", "Dangerous input: context=" + context + ", type(" + getTypeName() + ")=" + p.pattern() + ", input=" + input + (NullSafe.equals(orig,input) ? "" : ", orig=" + orig), context ); + } + } + + return input; + } + + /** + * checks input against blacklists. + * @param context The context to include in exception messages + * @param input the input to check + * @return input upon a successful check + * @throws ValidationException if the check fails. + */ + private String checkBlacklist(String context, String input) throws ValidationException + { + return checkBlacklist(context, input, input); + } + + /** + * checks input lengths + * @param context The context to include in exception messages + * @param input the input to check + * @param orig A origional input to include in exception + * messages. This is not included if it is the same as + * input. + * @return input upon a successful check + * @throws ValidationException if the check fails. + */ + private String checkLength(String context, String input, String orig) throws ValidationException + { + if (input.length() < minLength) { + throw new ValidationException( context + ": Invalid input. The minimum length of " + minLength + " characters was not met.", "Input does not meet the minimum length of " + minLength + " by " + (minLength - input.length()) + " characters: context=" + context + ", type=" + getTypeName() + "), input=" + input + (NullSafe.equals(input,orig) ? "" : ", orig=" + orig), context ); + } + + if (input.length() > maxLength) { + throw new ValidationException( context + ": Invalid input. The maximum length of " + maxLength + " characters was exceeded.", "Input exceeds maximum allowed length of " + maxLength + " by " + (input.length()-maxLength) + " characters: context=" + context + ", type=" + getTypeName() + ", orig=" + orig +", input=" + input, context ); + } + + return input; + } + + /** + * checks input lengths + * @param context The context to include in exception messages + * @param input the input to check + * @return input upon a successful check + * @throws ValidationException if the check fails. + */ + private String checkLength(String context, String input) throws ValidationException + { + return checkLength(context, input, input); + } + + /** + * checks input emptiness + * @param context The context to include in exception messages + * @param input the input to check + * @param orig A origional input to include in exception + * messages. This is not included if it is the same as + * input. + * @return input upon a successful check + * @throws ValidationException if the check fails. + */ + private String checkEmpty(String context, String input, String orig) throws ValidationException + { + if(!StringUtilities.isEmpty(input)) + return input; + if(allowNull) + return null; + throw new ValidationException( context + ": Input required.", "Input required: context=" + context + "), input=" + input + (NullSafe.equals(input,orig) ? "" : ", orig=" + orig), context ); + } + + /** + * checks input emptiness + * @param context The context to include in exception messages + * @param input the input to check + * @return input upon a successful check + * @throws ValidationException if the check fails. + */ + private String checkEmpty(String context, String input) throws ValidationException + { + return checkEmpty(context, input, input); + } + + /** + * {@inheritDoc} + */ + public String getValid( String context, String input ) throws ValidationException + { + String data = null; + + // check for empty/null + if(checkEmpty(context, input) == null) + return null; + + // check length + checkLength(context, input); + + // canonicalize + if (canonicalizeInput) { + data = encoder.canonicalize(input); + } else { + String message = String.format("Input validation excludes canonicalization. Context: %s Input: %s", context, input); + LOGGER.warning(Logger.SECURITY_AUDIT, message); + data = input; + } + + // check whitelist patterns + checkWhitelist(context, data, input); + + // check blacklist patterns + checkBlacklist(context, data, input); + + // validation passed + return data; + } + + /** + * {@inheritDoc} + */ + @Override + public String sanitize( String context, String input ) { + return whitelist( input, EncoderConstants.CHAR_ALPHANUMERICS ); + } + + +} + diff --git a/src/main/java/org/owasp/esapi/reference/validation/package.html b/src/main/java/org/owasp/esapi/reference/validation/package.html new file mode 100644 index 000000000..271bb16ea --- /dev/null +++ b/src/main/java/org/owasp/esapi/reference/validation/package.html @@ -0,0 +1,11 @@ + + + + + + + +This package contains data format-specific validation rule functions. + + + diff --git a/src/main/java/org/owasp/esapi/tags/BaseEncodeTag.java b/src/main/java/org/owasp/esapi/tags/BaseEncodeTag.java new file mode 100644 index 000000000..e52b7402b --- /dev/null +++ b/src/main/java/org/owasp/esapi/tags/BaseEncodeTag.java @@ -0,0 +1,70 @@ +/* + * 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.tags; + +import java.io.IOException; + +import javax.servlet.jsp.JspTagException; +import javax.servlet.jsp.JspWriter; +import javax.servlet.jsp.tagext.BodyTagSupport; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Encoder; + +/** Abstract base class for tags that just encode their bodies with Encoder methods. */ +public abstract class BaseEncodeTag extends BodyTagSupport +{ + private static final long serialVersionUID = 1L; + + /** + * Encode tag's content. + * @param content The tag's content as a String + * @param enc Encoder provided as a convinence. + * @return content encoded by the subclass's implementation. + */ + protected abstract String encode(String content, Encoder enc) throws JspTagException; + + /** + * After tag body parsing handler. This provides the necessary + * plubming to allow subclasses to just concern themselves with + * encoding a single string. + * @return {@link javax.servlet.jsp.tagext.Tag#SKIP_BODY} + * @throws JspTagException if writing to the bodyContent's + * enclosing writer throws an IOException. + */ + public int doAfterBody() throws JspTagException + { + String content; + JspWriter out; + + content = bodyContent.getString(); + out = bodyContent.getEnclosingWriter(); + + content = encode(content, ESAPI.encoder()); + try + { + out.print(content); + } + catch (IOException e) + { + throw new JspTagException("Error writing to body's enclosing JspWriter",e); + } + + bodyContent.clearBody(); + return SKIP_BODY; + } +} diff --git a/src/main/java/org/owasp/esapi/tags/ELEncodeFunctions.java b/src/main/java/org/owasp/esapi/tags/ELEncodeFunctions.java new file mode 100644 index 000000000..b8a2228f4 --- /dev/null +++ b/src/main/java/org/owasp/esapi/tags/ELEncodeFunctions.java @@ -0,0 +1,172 @@ +package org.owasp.esapi.tags; + +import java.io.UnsupportedEncodingException; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Encoder; +import org.owasp.esapi.errors.EncodingException; + +/** + * Static encoder methods for JSP EL expression functions. + */ +public class ELEncodeFunctions +{ + private static final String DEFAULT_ENCODING = "UTF-8"; + + /** + * Private constructor as this class shouldn't need to be + * instantiated. + */ + private ELEncodeFunctions() + { + } + + /** + * Base64 encode a string. UTF-8 is used to encode the string and no line wrapping is performed. + * @param str The string to encode. + * @return The base64 encoded String. + * @see Encoder#encodeForBase64(byte[],boolean) + * @throws UnsupportedEncodingException if UTF-8 is an unsupported character set. This should not happen as UTF-8 is required to be supported by the JVM spec. + */ + public static String encodeForBase64(String str) throws UnsupportedEncodingException + { + return encodeForBase64Charset(DEFAULT_ENCODING, str); + } + + /** + * Base64 encode a string with line wrapping. UTF-8 is used to encode the string and lines are wrapped at 64 characters.. + * @param str The string to encode. + * @return The base64 encoded String. + * @see Encoder#encodeForBase64(byte[],boolean) + * @throws UnsupportedEncodingException if UTF-8 is an unsupported character set. This should not happen as UTF-8 is required to be supported by the JVM spec. + */ + public static String encodeForBase64Wrap(String str) throws UnsupportedEncodingException + { + return encodeForBase64CharsetWrap(DEFAULT_ENCODING, str); + } + + /** + * Base64 encode a string after converting to bytes using the specified character set. No line wrapping is performed. + * @param charset The character set used to convert str to bytes. + * @param str The string to encode. + * @return The base64 encoded String. + * @see Encoder#encodeForBase64(byte[],boolean) + * @throws UnsupportedEncodingException if charset is an unsupported character set. + */ + public static String encodeForBase64Charset(String charset, String str) throws UnsupportedEncodingException + { + return ESAPI.encoder().encodeForBase64(str.getBytes(charset), false); + } + + /** + * Base64 encode a string after converting to bytes using the specified character set and wrapping lines. Lines are wrapped at 64 characters. + * @param charset The character set used to convert str to bytes. + * @param str The string to encode. + * @return The base64 encoded String. + * @see Encoder#encodeForBase64(byte[],boolean) + * @throws UnsupportedEncodingException if charset is an unsupported character set. + */ + public static String encodeForBase64CharsetWrap(String charset, String str) throws UnsupportedEncodingException + { + return ESAPI.encoder().encodeForBase64(str.getBytes(charset), true); + } + + /** + * Encode string for use in CSS. + * @param str The string to encode. + * @return str encoded for use in CSS. + * @see Encoder#encodeForCSS(String) + */ + public static String encodeForCSS(String str) + { + return ESAPI.encoder().encodeForCSS(str); + } + + /** + * Encode string for use in HTML. + * @param str The string to encode. + * @return str encoded for use in HTML. + * @see Encoder#encodeForHTML(String) + */ + public static String encodeForHTML(String str) + { + return ESAPI.encoder().encodeForHTML(str); + } + + /** + * Encode string for use in a HTML attribute. + * @param str The string to encode. + * @return str encoded for use in HTML attribute. + * @see Encoder#encodeForHTMLAttribute(String) + */ + public static String encodeForHTMLAttribute(String str) + { + return ESAPI.encoder().encodeForHTMLAttribute(str); + } + + /** + * Encode string for use in JavaScript. + * @param str The string to encode. + * @return str encoded for use in JavaScript. + * @see Encoder#encodeForJavaScript(String) + */ + public static String encodeForJavaScript(String str) + { + return ESAPI.encoder().encodeForJavaScript(str); + } + + /** + * Encode string for use in a URL. + * @param str The string to encode. + * @return str encoded for use in a URL. + * @see Encoder#encodeForURL(String) + */ + public static String encodeForURL(String str) throws EncodingException + { + return ESAPI.encoder().encodeForURL(str); + } + + /** + * Encode string for use in VBScript. + * @param str The string to encode. + * @return str encoded for use in VBScript. + * @see Encoder#encodeForVBScript(String) + */ + public static String encodeForVBScript(String str) + { + return ESAPI.encoder().encodeForVBScript(str); + } + + /** + * Encode string for use in XML. + * @param str The string to encode. + * @return str encoded for use in XML. + * @see Encoder#encodeForXML(String) + */ + public static String encodeForXML(String str) + { + return ESAPI.encoder().encodeForXML(str); + } + + /** + * Encode string for use in a XML attribute. + * @param str The string to encode. + * @return str encoded for use in XML attribute. + * @see Encoder#encodeForXMLAttribute(String) + */ + public static String encodeForXMLAttribute(String str) + { + return ESAPI.encoder().encodeForXMLAttribute(str); + } + + /** + * Encode string for use in XPath. + * @param str The string to encode. + * @return str encoded for use in XPath. + * @see Encoder#encodeForXPath(String) + */ + public static String encodeForXPath(String str) + { + return ESAPI.encoder().encodeForXPath(str); + } +} diff --git a/src/main/java/org/owasp/esapi/tags/EncodeForBase64Tag.java b/src/main/java/org/owasp/esapi/tags/EncodeForBase64Tag.java new file mode 100644 index 000000000..a9300ffa4 --- /dev/null +++ b/src/main/java/org/owasp/esapi/tags/EncodeForBase64Tag.java @@ -0,0 +1,82 @@ +package org.owasp.esapi.tags; + +import java.io.UnsupportedEncodingException; + +import javax.servlet.jsp.JspTagException; + +import org.owasp.esapi.Encoder; + +/** + * JSP tag that encodes its body using Base64. + */ +public class EncodeForBase64Tag extends BaseEncodeTag +{ + private static final long serialVersionUID = 3L; + /** @serial Flag determining line wrapping */ + private boolean wrap = false; + /** + * @serial Charset to use when converting content from a String + * to byte[]. + */ + private String encoding = "UTF-8"; + + /** + * Encode tag's content using Base64. + * @param content The tag's content as a String + * @param enc Encoder used to call + * {@link Encoder#encodeForBase64(byte[], boolean)} + * @return content encoded in Base64 + */ + protected String encode(String content, Encoder enc) throws JspTagException + { + try + { + return enc.encodeForBase64(content.getBytes(encoding), wrap); + } + catch(UnsupportedEncodingException e) + { + throw new JspTagException("Unsupported encoding " + enc,e); + } + } + + /** + * Set the encoding used to convert the content to bytes for + * encoding. This defaults to UTF-8 if not specified. + * @param encoding The encoding passed to {@link String#getBytes(String)}. + */ + public void setEncoding(String encoding) + { + this.encoding=encoding; + } + + /** + * Get the encoding used to convert the content to bytes for + * encoding. + * @return encoding The encoding passed to + * {@link String#getBytes(String)}. + */ + public String getEncoding() + { + return encoding; + } + + /** + * Set whether line wrapping at 64 characters is performed. This + * defaults to false. + * @param wrap flag determining wrapping. + */ + public void setWrap(boolean wrap) + { + this.wrap=wrap; + } + + /** + * Get whether line wrapping at 64 characters is performed. This + * defaults to false. + * @return value of flag determining wrapping. + */ + public boolean getWrap() + { + return wrap; + } +} diff --git a/src/main/java/org/owasp/esapi/tags/EncodeForCSSTag.java b/src/main/java/org/owasp/esapi/tags/EncodeForCSSTag.java new file mode 100644 index 000000000..b2e6452cb --- /dev/null +++ b/src/main/java/org/owasp/esapi/tags/EncodeForCSSTag.java @@ -0,0 +1,23 @@ +package org.owasp.esapi.tags; + +import org.owasp.esapi.Encoder; + +/** + * JSP tag that encodes its body for use in CSS. + */ +public class EncodeForCSSTag extends BaseEncodeTag +{ + private static final long serialVersionUID = 3L; + + /** + * Encode tag's content for usage in CSS. + * @param content The tag's content as a String + * @param enc Encoder used to call + * {@link Encoder#encodeForCSS(String)} + * @return content encoded for usage in CSS + */ + protected String encode(String content, Encoder enc) + { + return enc.encodeForCSS(content); + } +} diff --git a/src/main/java/org/owasp/esapi/tags/EncodeForHTMLAttributeTag.java b/src/main/java/org/owasp/esapi/tags/EncodeForHTMLAttributeTag.java new file mode 100644 index 000000000..969bb0015 --- /dev/null +++ b/src/main/java/org/owasp/esapi/tags/EncodeForHTMLAttributeTag.java @@ -0,0 +1,39 @@ +/* + * 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.tags; + +import org.owasp.esapi.Encoder; + +/** + * JSP tag that encodes its body for use in a HTML attribute. + */ +public class EncodeForHTMLAttributeTag extends BaseEncodeTag +{ + private static final long serialVersionUID = 3L; + + /** + * Encode tag's content for usage as a HTML attribute. + * @param content The tag's content as a String + * @param enc Encoder used to call + * {@link Encoder#encodeForHTMLAttribute(String)} + * @return content encoded for usage as a HTML attribute + */ + protected String encode(String content, Encoder enc) + { + return enc.encodeForHTMLAttribute(content); + } +} diff --git a/src/main/java/org/owasp/esapi/tags/EncodeForHTMLTag.java b/src/main/java/org/owasp/esapi/tags/EncodeForHTMLTag.java new file mode 100644 index 000000000..d9584dffa --- /dev/null +++ b/src/main/java/org/owasp/esapi/tags/EncodeForHTMLTag.java @@ -0,0 +1,39 @@ +/* + * 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.tags; + +import org.owasp.esapi.Encoder; + +/** + * JSP tag that encodes its body for use in HTML. + */ +public class EncodeForHTMLTag extends BaseEncodeTag +{ + private static final long serialVersionUID = 3L; + + /** + * Encode tag's content for usage in HTML. + * @param content The tag's content as a String + * @param enc Encoder used to call + * {@link Encoder#encodeForHTML(String)} + * @return content encoded for usage in HTML + */ + protected String encode(String content, Encoder enc) + { + return enc.encodeForHTML(content); + } +} diff --git a/src/main/java/org/owasp/esapi/tags/EncodeForJavaScriptTag.java b/src/main/java/org/owasp/esapi/tags/EncodeForJavaScriptTag.java new file mode 100644 index 000000000..b8d3c5483 --- /dev/null +++ b/src/main/java/org/owasp/esapi/tags/EncodeForJavaScriptTag.java @@ -0,0 +1,23 @@ +package org.owasp.esapi.tags; + +import org.owasp.esapi.Encoder; + +/** + * JSP tag that encodes its body for use in JavaScript. + */ +public class EncodeForJavaScriptTag extends BaseEncodeTag +{ + private static final long serialVersionUID = 3L; + + /** + * Encode tag's content for usage in JavaScript + * @param content The tag's content as a String + * @param enc Encoder used to call + * {@link Encoder#encodeForJavaScript(String)} + * @return content encoded for usage in JavaScript + */ + protected String encode(String content, Encoder enc) + { + return enc.encodeForJavaScript(content); + } +} diff --git a/src/main/java/org/owasp/esapi/tags/EncodeForURLTag.java b/src/main/java/org/owasp/esapi/tags/EncodeForURLTag.java new file mode 100644 index 000000000..ab9a6734c --- /dev/null +++ b/src/main/java/org/owasp/esapi/tags/EncodeForURLTag.java @@ -0,0 +1,34 @@ +package org.owasp.esapi.tags; + +import javax.servlet.jsp.JspTagException; + +import org.owasp.esapi.Encoder; +import org.owasp.esapi.errors.EncodingException; + +/** + * JSP tag that encodes its body for use in a URL. + */ +public class EncodeForURLTag extends BaseEncodeTag +{ + private static final long serialVersionUID = 3L; + + /** + * Encode tag's content for usage in a URL. + * @param content The tag's content as a String + * @param enc Encoder used to call + * {@link Encoder#encodeForURL(String)} + * @return content encoded for usage in a URL + * @throws EncodingException if {@link Encoder#encodeForURL(String)} does. + */ + protected String encode(String content, Encoder enc) throws JspTagException + { + try + { + return enc.encodeForURL(content); + } + catch(EncodingException e) + { + throw new JspTagException("Unable to encode to URL encoding", e); + } + } +} diff --git a/src/main/java/org/owasp/esapi/tags/EncodeForVBScriptTag.java b/src/main/java/org/owasp/esapi/tags/EncodeForVBScriptTag.java new file mode 100644 index 000000000..033ef06f9 --- /dev/null +++ b/src/main/java/org/owasp/esapi/tags/EncodeForVBScriptTag.java @@ -0,0 +1,39 @@ +/* + * 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.tags; + +import org.owasp.esapi.Encoder; + +/** + * JSP tag that encodes its body for use in VBScript. + */ +public class EncodeForVBScriptTag extends BaseEncodeTag +{ + private static final long serialVersionUID = 3L; + + /** + * Encode tag's content for usage in VBScript. + * @param content The tag's content as a String + * @param enc Encoder used to call + * {@link Encoder#encodeForVBScript(String)} + * @return content encoded for usage in VBScript + */ + protected String encode(String content, Encoder enc) + { + return enc.encodeForVBScript(content); + } +} diff --git a/src/main/java/org/owasp/esapi/tags/EncodeForXMLAttributeTag.java b/src/main/java/org/owasp/esapi/tags/EncodeForXMLAttributeTag.java new file mode 100644 index 000000000..7b2a1264c --- /dev/null +++ b/src/main/java/org/owasp/esapi/tags/EncodeForXMLAttributeTag.java @@ -0,0 +1,23 @@ +package org.owasp.esapi.tags; + +import org.owasp.esapi.Encoder; + +/** + * JSP tag that encodes its body for use in a XML attribute. + */ +public class EncodeForXMLAttributeTag extends BaseEncodeTag +{ + private static final long serialVersionUID = 3L; + + /** + * Encode tag's content for usage as a XML attribute. + * @param content The tag's content as a String + * @param enc Encoder used to call + * {@link Encoder#encodeForXMLAttribute(String)} + * @return content encoded for usage as a XML attribute + */ + protected String encode(String content, Encoder enc) + { + return enc.encodeForXMLAttribute(content); + } +} diff --git a/src/main/java/org/owasp/esapi/tags/EncodeForXMLTag.java b/src/main/java/org/owasp/esapi/tags/EncodeForXMLTag.java new file mode 100644 index 000000000..f06ad3710 --- /dev/null +++ b/src/main/java/org/owasp/esapi/tags/EncodeForXMLTag.java @@ -0,0 +1,23 @@ +package org.owasp.esapi.tags; + +import org.owasp.esapi.Encoder; + +/** + * JSP tag that encodes its body for use in XML. + */ +public class EncodeForXMLTag extends BaseEncodeTag +{ + private static final long serialVersionUID = 3L; + + /** + * Encode tag's content for usage in XML. + * @param content The tag's content as a String + * @param enc Encoder used to call + * {@link Encoder#encodeForXML(String)} + * @return content encoded for usage in XML + */ + protected String encode(String content, Encoder enc) + { + return enc.encodeForXML(content); + } +} diff --git a/src/main/java/org/owasp/esapi/tags/EncodeForXPathTag.java b/src/main/java/org/owasp/esapi/tags/EncodeForXPathTag.java new file mode 100644 index 000000000..0a36c32c0 --- /dev/null +++ b/src/main/java/org/owasp/esapi/tags/EncodeForXPathTag.java @@ -0,0 +1,23 @@ +package org.owasp.esapi.tags; + +import org.owasp.esapi.Encoder; + +/** + * JSP tag that encodes its body for use in XPath. + */ +public class EncodeForXPathTag extends BaseEncodeTag +{ + private static final long serialVersionUID = 3L; + + /** + * Encode tag's content for usage in XPath. + * @param content The tag's content as a String + * @param enc Encoder used to call + * {@link Encoder#encodeForXPath(String)} + * @return content encoded for usage in XPath + */ + protected String encode(String content, Encoder enc) + { + return enc.encodeForXPath(content); + } +} diff --git a/src/main/java/org/owasp/esapi/tags/package.html b/src/main/java/org/owasp/esapi/tags/package.html new file mode 100644 index 000000000..e6df37a86 --- /dev/null +++ b/src/main/java/org/owasp/esapi/tags/package.html @@ -0,0 +1,12 @@ + + + + + + + +This package contains sample JSP tags that demonstrate how to use the ESAPI functions +to protect an application from within a JSP page. + + + diff --git a/src/main/java/org/owasp/esapi/util/ByteConversionUtil.java b/src/main/java/org/owasp/esapi/util/ByteConversionUtil.java new file mode 100644 index 000000000..abb82c018 --- /dev/null +++ b/src/main/java/org/owasp/esapi/util/ByteConversionUtil.java @@ -0,0 +1,145 @@ +/* + * 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 © 2010 - The OWASP Foundation + */ +package org.owasp.esapi.util; + +/** + * Conversion to/from byte arrays to/from short, int, long. The assumption + * is that they byte arrays are in network byte order (i.e., big-endian + * ordered). + * + * @see org.owasp.esapi.crypto.CipherTextSerializer + * @author kevin.w.wall@gmail.com + */ +public class ByteConversionUtil { + + ////////// Convert from short, int, long to byte array. ////////// + + /** + * Returns a byte array containing 2 network byte ordered bytes representing + * the given {@code short}. + * + * @param input An {@code short} to convert to a byte array. + * @return A byte array representation of an {@code short} in network byte + * order (i.e., big-endian order). + */ + public static byte[] fromShort(short input) { + byte[] output = new byte[2]; + output[0] = (byte) (input >> 8); + output[1] = (byte) input; + return output; + } + + /** + * Returns a byte array containing 4 network byte-ordered bytes representing the + * given {@code int}. + * + * @param input An {@code int} to convert to a byte array. + * @return A byte array representation of an {@code int} in network byte order + * (i.e., big-endian order). + */ + public static byte[] fromInt(int input) { + byte[] output = new byte[4]; + output[0] = (byte) (input >> 24); + output[1] = (byte) (input >> 16); + output[2] = (byte) (input >> 8); + output[3] = (byte) input; + return output; + } + + /** + * Returns a byte array containing 8 network byte-ordered bytes representing + * the given {@code long}. + * + * @param input The {@code long} to convert to a {@code byte} array. + * @return A byte array representation of a {@code long}. + */ + public static byte[] fromLong(long input) { + byte[] output = new byte[8]; + output[0] = (byte) (input >> 56); + output[1] = (byte) (input >> 48); + output[2] = (byte) (input >> 40); + output[3] = (byte) (input >> 32); + output[4] = (byte) (input >> 24); + output[5] = (byte) (input >> 16); + output[6] = (byte) (input >> 8); + output[7] = (byte) input; + return output; + } + + ////////// Convert from byte array to short, int, long. ////////// + + /** + * Converts a given byte array to an {@code short}. Bytes are expected in + * network byte order. + * + * @param input A network byte-ordered representation of an {@code short}, + * so exactly 2 bytes are expected. + * @return The {@code short} value represented by the input array. + */ + public static short toShort(byte[] input) { + if ( input == null ) { + throw new IllegalArgumentException("input: parameter may not be null."); + } + if ( input.length != 2 ) { + throw new IllegalArgumentException("input: Byte array length must be 2."); + } + short output = 0; + output = (short)(((input[0] & 0xff) << 8) | (input[1] & 0xff)); + return output; + } + + /** + * Converts a given byte array to an {@code int}. Bytes are expected in + * network byte order. + * + * @param input A network byte-ordered representation of an {@code int}. + * Must be exactly 4 bytes. + * @return The {@code int} value represented by the input array. + */ + public static int toInt(byte[] input) { + if ( input == null ) { + throw new IllegalArgumentException("input: parameter may not be null."); + } + if ( input.length != 4 ) { + throw new IllegalArgumentException("input: Byte array length must be 4."); + } + int output = 0; + output = ((input[0] & 0xff) << 24) | ((input[1] & 0xff) << 16) | + ((input[2] & 0xff) << 8) | (input[3] & 0xff); + return output; + } + + /** + * Converts a given byte array to a {@code long}. Bytes are expected in + * network byte + * + * @param input A network byte-ordered representation of a {@code long}. + * Must be exactly 8 bytes. + * @return The {@code long} value represented by the input array + */ + public static long toLong(byte[] input) { + if ( input == null ) { + throw new IllegalArgumentException("input: parameter may not be null."); + } + if ( input.length != 8 ) { + throw new IllegalArgumentException("input: Byte array length must be 8."); + } + long output = 0; + output = ((long)(input[0] & 0xff) << 56); + output |= ((long)(input[1] & 0xff) << 48); + output |= ((long)(input[2] & 0xff) << 40); + output |= ((long)(input[3] & 0xff) << 32); + output |= ((long)(input[4] & 0xff) << 24); + output |= ((long)(input[5] & 0xff) << 16); + output |= ((long)(input[6] & 0xff) << 8); + output |= (input[7] & 0xff); + return output; + } +} diff --git a/src/main/java/org/owasp/esapi/util/CollectionsUtil.java b/src/main/java/org/owasp/esapi/util/CollectionsUtil.java new file mode 100644 index 000000000..a4284030e --- /dev/null +++ b/src/main/java/org/owasp/esapi/util/CollectionsUtil.java @@ -0,0 +1,115 @@ +/** + * + */ +package org.owasp.esapi.util; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +/** + * @author Neil Matatall (neil.matatall .at. gmail.com) + * + * Are these necessary? Are there any libraries or java.lang classes to take + * care of the conversions? + * + * FIXME: we can convert to using this, but it requires that the array be of Character, not char + * new HashSet(Arrays.asList(array)) + * + */ +public class CollectionsUtil +{ + private static final char[] EMPTY_CHAR_ARRAY = new char[0]; + + /** + * Converts an array of chars to a Set of Characters. + * @param array the contents of the new Set + * @return a Set containing the elements in the array + */ + public static Set arrayToSet(char...array) + { + Set toReturn; + + if(array == null) + return new HashSet(); + toReturn = new HashSet(array.length); + for (char c : array) { + toReturn.add(c); + } + return toReturn; + } + + /** + * Convert a char array to an unmodifiable Set. + * @param array the contents of the new Set + * @return an unmodifiable Set containing the elements in the + * array. + */ + public static Set arrayToUnmodifiableSet(char...array) + { + if(array == null) + return Collections.emptySet(); + if(array.length == 1) + return Collections.singleton(array[0]); + return Collections.unmodifiableSet(arrayToSet(array)); + } + + /** + * Convert a String to a char array + * @param str The string to convert + * @return character array containing the characters in str. An + * empty array is returned if str is null. + */ + public static char[] strToChars(String str) + { + int len; + char[] ret; + + if(str == null) + return EMPTY_CHAR_ARRAY; + len = str.length(); + ret = new char[len]; + str.getChars(0,len,ret,0); + return ret; + } + + /** + * Convert a String to a set of characters. + * @param str The string to convert + * @return A set containing the characters in str. An empty set + * is returned if str is null. + */ + public static Set strToSet(String str) + { + Set set; + + if(str == null) + return new HashSet(); + set = new HashSet(str.length()); + for(int i=0;i strToUnmodifiableSet(String str) + { + if(str == null) + return Collections.emptySet(); + if(str.length() == 1) + return Collections.singleton(str.charAt(0)); + return Collections.unmodifiableSet(strToSet(str)); + } + + /** + * Private constructor to prevent instantiation. + */ + private CollectionsUtil() + { + } +} diff --git a/src/main/java/org/owasp/esapi/util/DefaultMessageUtil.java b/src/main/java/org/owasp/esapi/util/DefaultMessageUtil.java new file mode 100644 index 000000000..ee9de4286 --- /dev/null +++ b/src/main/java/org/owasp/esapi/util/DefaultMessageUtil.java @@ -0,0 +1,49 @@ +/** + * 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 Pawan Singh (pawan.singh@owasp.org) OWASP + * @created 2009 + */ +package org.owasp.esapi.util; + +import java.text.MessageFormat; +import java.util.Locale; +import java.util.ResourceBundle; + +import org.owasp.esapi.ESAPI; + +/** + * @author Pawan Singh (pawan.singh@owasp.org) + * + */ +public class DefaultMessageUtil { + + private final String DEFAULT_LOCALE_LANG = "en"; + private final String DEFAULT_LOCALE_LOC = "US"; + + private ResourceBundle messages = null; + + public void initialize() { + try { + messages = ResourceBundle.getBundle("ESAPI", ESAPI.authenticator().getCurrentUser().getLocale()); + } catch (Exception e) { + messages = ResourceBundle.getBundle("ESAPI", new Locale(DEFAULT_LOCALE_LANG,DEFAULT_LOCALE_LOC)); + } + } + + + public String getMessage(String msgKey, Object[] arguments) { + + initialize(); + return MessageFormat.format( messages.getString(msgKey), arguments ); + } +} \ No newline at end of file diff --git a/src/main/java/org/owasp/esapi/util/NullSafe.java b/src/main/java/org/owasp/esapi/util/NullSafe.java new file mode 100644 index 000000000..a0bee5f55 --- /dev/null +++ b/src/main/java/org/owasp/esapi/util/NullSafe.java @@ -0,0 +1,52 @@ +package org.owasp.esapi.util; + +public class NullSafe +{ + /** + * Class should not be instantiated. + */ + private NullSafe() + { + } + + /** + * {@link Object#equals(Object)} that safely handles nulls. + * @param a First object + * @param b Second object + * @return true if a == b or a.equals(b). false otherwise. + */ + public static boolean equals(Object a, Object b) + { + if(a==b) // short cut same object + return true; + if(a == null) + return (b == null); + if(b == null) + return false; + return a.equals(b); + } + + /** + * {@link Object#hashCode()} of an object. + * @param o Object to get a hashCode for. + * @return 0 if o is null. Otherwise o.hashCode(). + */ + public static int hashCode(Object o) + { + if(o == null) + return 0; + return o.hashCode(); + } + + /** + * {@link Object#toString()} of an object. + * @param o Object to get a String for. + * @return "(null)" o is null. Otherwise o.toString(). + */ + public static String toString(Object o) + { + if(o == null) + return "(null)"; + return o.toString(); + } +} diff --git a/src/main/java/org/owasp/esapi/util/ObjFactory.java b/src/main/java/org/owasp/esapi/util/ObjFactory.java new file mode 100644 index 000000000..3faa6a847 --- /dev/null +++ b/src/main/java/org/owasp/esapi/util/ObjFactory.java @@ -0,0 +1,239 @@ +/* + * 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) 2009 - The OWASP Foundation + */ +package org.owasp.esapi.util; + +import org.owasp.esapi.errors.ConfigurationException; + +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.concurrent.ConcurrentHashMap; + +/** + * A generic object factory to create an object of class T. T must be a concrete + * class that has a no-argument public constructor or an implementor of the Singleton pattern + * that has a no-arg static getInstance method. If the class being created has a getInstance + * method, it will be used as a singleton and newInstance() will never be called on the + * class no matter how many times it comes through this factory. + * + *

+ * Typical use is something like: + *

+ *         import com.example.interfaces.DrinkingEstablishment;
+ *         import com.example.interfaces.Beer;
+ *         ...
+ *         // Typically these would be populated from some Java properties file
+ *         String barName = "com.example.foo.Bar";
+ *         String beerBrand = "com.example.brewery.Guinness";
+ *         ...
+ *         DrinkingEstablishment bar = ObjFactory.make(barName, "DrinkingEstablishment");
+ *         Beer beer = ObjFactory.make(beerBrand, "Beer");
+ *        bar.drink(beer);    // Drink a Guinness beer at the foo Bar. :)
+ *        ...
+ * 
+ *

+ * Copyright (c) 2009 - The OWASP Foundation + *

+ * @author kevin.w.wall@gmail.com + * @author Chris Schmidt ( chrisisbeef .at. gmail.com ) + */ +public class ObjFactory { + + private static final int CACHE_INITIAL_CAPACITY = 32; + private static final float CACHE_LOAD_FACTOR = 0.75F; + private static final ConcurrentHashMap> CLASSES_CACHE = new ConcurrentHashMap<>(CACHE_INITIAL_CAPACITY, CACHE_LOAD_FACTOR); + private static final ConcurrentHashMap METHODS_CACHE = new ConcurrentHashMap<>(CACHE_INITIAL_CAPACITY, CACHE_LOAD_FACTOR); + private static boolean cacheEnabled = true; + + /** + * Create an object based on the className parameter. + * + * @param className The name of the class to construct. Should be a fully qualified name and + * generally the same as type T + * @param typeName A type name used in error messages / exceptions. + * @return An object of type className, which is cast to type T. + * @throws ConfigurationException thrown if class name not found in class path, or does not + * have a public, no-argument constructor, or is not a concrete class, or if it is + * not a sub-type of T (or T itself). Usually this is + * caused by a misconfiguration of the class names specified in the ESAPI.properties + * file. Also thrown if the CTOR of the specified className throws + * an Exception of some type. + */ + @SuppressWarnings({ "unchecked" }) // Added because of Eclipse warnings, but ClassCastException IS caught. + public static T make(String className, String typeName) throws ConfigurationException { + Object obj = null; + String errMsg = null; + try { + if (null == className || "".equals(className) ) { + throw new IllegalArgumentException("Classname cannot be null or empty."); + } + if (null == typeName || "".equals(typeName) ) { + // No big deal...just use "[unknown?]" for this as it's only for an err msg. + typeName = "[unknown?]"; // CHECKME: Any better suggestions? + } + + Class theClass = loadClassByStringName(className); + + try { + Method singleton = findSingletonCreateMethod(className, theClass); + + obj = singleton.invoke( null ); + } catch (NoSuchMethodException e) { + // This is a no-error exception, if this is caught we will continue on assuming the implementation was + // not meant to be used as a singleton. + obj = theClass.newInstance(); + } catch (SecurityException e) { + // The class is meant to be singleton, however, the SecurityManager restricts us from calling the + // getInstance method on the class, thus this is a configuration issue and a ConfigurationException + // is thrown + throw new ConfigurationException( "The SecurityManager has restricted the object factory from getting a reference to the singleton implementation " + + "of the class [" + className + "]", e ); + } + + return (T)obj; // Eclipse warning here if @SupressWarnings omitted. + + // Issue 66 - Removed System.out calls as we are throwing an exception in each of these cases + // anyhow. + } catch( IllegalArgumentException ex ) { + errMsg = ex.toString() + " " + typeName + " type name cannot be null or empty."; + throw new ConfigurationException(errMsg, ex); + }catch ( ClassNotFoundException ex ) { + errMsg = ex.toString() + " " + typeName + " class (" + className + ") must be in class path."; + throw new ConfigurationException(errMsg, ex); + } catch( InstantiationException ex ) { + errMsg = ex.toString() + " " + typeName + " class (" + className + ") must be concrete."; + throw new ConfigurationException(errMsg, ex); + } catch( IllegalAccessException ex ) { + errMsg = ex.toString() + " " + typeName + " class (" + className + ") must have a public, no-arg constructor."; + throw new ConfigurationException(errMsg, ex); + } catch( ClassCastException ex ) { + errMsg = ex.toString() + " " + typeName + " class (" + className + ") must be a subtype of T in ObjFactory"; + throw new ConfigurationException(errMsg, ex); + } catch( Exception ex ) { + // Because we are using reflection, we want to catch any checked or unchecked Exceptions and + // re-throw them in a way we can handle them. Because using reflection to construct the object, + // we can't have the compiler notify us of uncaught exceptions. For example, JavaEncryptor() + // CTOR can throw [well, now it can] an EncryptionException if something goes wrong. That case + // is taken care of here. + // + // CHECKME: Should we first catch RuntimeExceptions so we just let unchecked Exceptions go through + // unaltered??? + // + errMsg = ex.toString() + " " + typeName + " class (" + className + ") CTOR threw exception."; + throw new ConfigurationException(errMsg, ex); + } + // DISCUSS: Should we also catch ExceptionInInitializerError here? See Google Issue #61 comments. + } + + /** + * Control whether cache for classes and method names should be enabled or disabled. Initial state is enabled. + * Ordinally, you are not expected to want to / have to call this method. It's major purpose is a "just-in-case" + * something goes wrong is some weird context where multiple ESAPI jars are loaded into a give application and something + * goes wrong, etc. A secondary purpose is it allows us to easily disable the cache so we can measure its time savings. + * + * @param enable true - enable cache; false - disable cache + */ + public static void setCache(boolean enable) { + cacheEnabled = enable; + } + + /** + * Load the class in cache, or load by the classloader and cache it + * + * @param className The name of the class to construct. Should be a fully qualified name + * @return The target class + * @throws ClassNotFoundException Failed to load class by the className + */ + private static Class loadClassByStringName(String className) throws ClassNotFoundException { + Class clazz; + if (cacheEnabled && CLASSES_CACHE.containsKey(className)) { + clazz = CLASSES_CACHE.get(className); + } else { + clazz = Class.forName(className); + if ( cacheEnabled ) CLASSES_CACHE.putIfAbsent(className, clazz); + } + return clazz; + } + + /** + * Find the method to create a singleton object + * + * @param className The name of the class to construct. Should be a fully qualified name + * @param theClass The class loaded in prior + * @return The method to create a singleton object + * @throws NoSuchMethodException Failed to find the target method + */ + private static Method findSingletonCreateMethod(String className, Class theClass) throws NoSuchMethodException { + MethodWrappedInfo singleton = loadMethodByStringName(className,theClass); + + // If the implementation class contains a getInstance method that is not static, this is an invalid + // object configuration and a ConfigurationException will be thrown. + if (!singleton.isStaticMethod()) { + throw singleton.getNonStaticEx(); + } + return singleton.getMethod(); + } + + /** + * + * @param className The name of the class to construct. Should be a fully qualified name + * @param theClass The class loaded in prior + * @return Wrapped data, contains the method object and the method is static method or not + * @throws NoSuchMethodException Failed to find the target method + */ + private static MethodWrappedInfo loadMethodByStringName(String className, Class theClass) throws NoSuchMethodException { + String methodName = className + "getInstance"; + MethodWrappedInfo methodInfo; + if (cacheEnabled && METHODS_CACHE.containsKey(methodName)) { + methodInfo = METHODS_CACHE.get(methodName); + } else { + Method method = theClass.getMethod("getInstance"); + boolean staticMethod = Modifier.isStatic(method.getModifiers()); + ConfigurationException nonStaticEx = staticMethod ? null : + new ConfigurationException("Class [" + className + "] contains a non-static getInstance method."); + methodInfo = new MethodWrappedInfo(method, staticMethod, nonStaticEx); + if ( cacheEnabled ) METHODS_CACHE.putIfAbsent(methodName, methodInfo); + } + return methodInfo; + } + + /** + * Not instantiable + */ + private ObjFactory() { } + + /** + * Wrapped data, contains the method object and the method is static method or not.
+ * The goal to store the boolean value in field staticMethod is reduce the check times: check once, use many times.
+ * The goal to store the exception in field nonStaticException is reduce the cost of new Exception(): create once, use many times. + */ + private static class MethodWrappedInfo { + private Method method; + private boolean staticMethod; + private ConfigurationException nonStaticEx; + + MethodWrappedInfo(Method method, boolean staticMethod, ConfigurationException nonStaticEx) { + this.method = method; + this.staticMethod = staticMethod; + this.nonStaticEx = nonStaticEx; + } + + Method getMethod() { + return method; + } + + boolean isStaticMethod() { + return staticMethod; + } + + ConfigurationException getNonStaticEx() { + return nonStaticEx; + } + } +} diff --git a/src/main/java/org/owasp/esapi/util/package.html b/src/main/java/org/owasp/esapi/util/package.html new file mode 100644 index 000000000..2be7784a5 --- /dev/null +++ b/src/main/java/org/owasp/esapi/util/package.html @@ -0,0 +1,10 @@ + + + + + + +This package contains ESAPI utility classes used throughout the +reference implementation of ESAPI but may also be directly useful. + + \ No newline at end of file diff --git a/src/main/java/org/owasp/esapi/waf/ConfigurationException.java b/src/main/java/org/owasp/esapi/waf/ConfigurationException.java new file mode 100644 index 000000000..8368e222a --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/ConfigurationException.java @@ -0,0 +1,42 @@ +/** + * 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) 2009 - 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 2009 + */ +package org.owasp.esapi.waf; + +import nu.xom.ValidityException; + +import org.owasp.esapi.errors.EnterpriseSecurityException; + +/** + * The Exception to be thrown when there is an error parsing a policy file. + * + * @author Arshan Dabirsiaghi + * @see org.owasp.esapi.waf.configuration.ConfigurationParser + * + */ +public class ConfigurationException extends EnterpriseSecurityException { + + protected static final long serialVersionUID = 1L; + + public ConfigurationException(String userMsg, String logMsg) { + super(userMsg,logMsg); + } + + public ConfigurationException(String userMsg, String logMsg, + Throwable t) { + super(userMsg,logMsg,t); + } + +} diff --git a/src/main/java/org/owasp/esapi/waf/ESAPIWebApplicationFirewallFilter.java b/src/main/java/org/owasp/esapi/waf/ESAPIWebApplicationFirewallFilter.java new file mode 100644 index 000000000..c1e7734f6 --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/ESAPIWebApplicationFirewallFilter.java @@ -0,0 +1,503 @@ +/** + * 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) 2009 - 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 2009 + */ +package org.owasp.esapi.waf; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.List; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.fileupload.FileUploadException; +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Logger; +import org.owasp.esapi.waf.actions.Action; +import org.owasp.esapi.waf.actions.BlockAction; +import org.owasp.esapi.waf.actions.DefaultAction; +import org.owasp.esapi.waf.actions.RedirectAction; +import org.owasp.esapi.waf.configuration.AppGuardianConfiguration; +import org.owasp.esapi.waf.configuration.ConfigurationParser; +import org.owasp.esapi.waf.internal.InterceptingHTTPServletRequest; +import org.owasp.esapi.waf.internal.InterceptingHTTPServletResponse; +import org.owasp.esapi.waf.rules.Rule; + +/** + * This is the main class for the ESAPI Web Application Firewall (WAF). It is a + * standard J2EE servlet filter that, in different methods, invokes the reading + * of the configuration file and handles the runtime processing and enforcing of + * the developer-specified rules. + * + * Ideally the filter should be configured to catch all requests (/*) in + * web.xml. If there are URL segments that need to be extremely fast and don't + * require any protection, the pattern may be modified with extreme caution. + * + * @author Arshan Dabirsiaghi + * + */ +public class ESAPIWebApplicationFirewallFilter implements Filter { + + private AppGuardianConfiguration appGuardConfig; + + private static final String CONFIGURATION_FILE_PARAM = "configuration"; + private static final String LOGGING_FILE_PARAM = "log_settings"; + private static final String POLLING_TIME_PARAM = "polling_time"; + + private static final int DEFAULT_POLLING_TIME = 30000; + + private String configurationFilename = null; + + private long pollingTime; + + private long lastConfigReadTime; + + // private static final String FAUX_SESSION_COOKIE = "FAUXSC"; + // private static final String SESSION_COOKIE_CANARY = + // "org.owasp.esapi.waf.canary"; + + private FilterConfig fc; + + private final Logger logger = ESAPI.getLogger(ESAPIWebApplicationFirewallFilter.class); + + /** + * This function is used in testing to dynamically alter the configuration. + * + * @param policyFilePath + * The path to the policy file + * @param webRootDir + * The root directory of the web application. + * @throws FileNotFoundException + * if the policy file cannot be located + */ + public void setConfiguration(String policyFilePath, String webRootDir) throws FileNotFoundException { + + FileInputStream inputStream = null; + + try { + inputStream = new FileInputStream(new File(policyFilePath)); + appGuardConfig = ConfigurationParser.readConfigurationFile(inputStream, webRootDir); + lastConfigReadTime = System.currentTimeMillis(); + configurationFilename = policyFilePath; + } catch (ConfigurationException e) { + // TODO: It would be ideal if this method threw the + // ConfigurationException rather than catching it and + // writing the error to the console. + e.printStackTrace(); + } finally { + if (inputStream != null) { + try { + inputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + + public AppGuardianConfiguration getConfiguration() { + return appGuardConfig; + } + + /** + * + * This function is invoked at application startup and when the + * configuration file polling period has elapsed and a change in the + * configuration file has been detected. + * + * It's main purpose is to read the configuration file and establish the + * configuration object model for use at runtime during the + * doFilter() method. + */ + public void init(FilterConfig fc) throws ServletException { + + /* + * This variable is saved so that we can retrieve it later to re-invoke + * this function. + */ + this.fc = fc; + + logger.debug(Logger.EVENT_SUCCESS, ">> Initializing ESAPI WAF"); + /* + * Pull logging file. -- We now ignore this arg, but will log something + * letting users know we are ignoring it, because many of them never + * seem to read the release notes. And this is probably better than + * throwing an exception. + */ + String logSettingsFilename = fc.getInitParameter(LOGGING_FILE_PARAM); + if ( logSettingsFilename != null ) { + logger.warning(Logger.EVENT_FAILURE, ">> Since ESAPI 2.5.0.0, ESAPI WAF ignoring parameter '" + + LOGGING_FILE_PARAM + "; for further details, see " + + "https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/esapi4java-core-2.5.0.0-release-notes.txt"); + + } + + /* + * Pull main configuration file. + */ + + configurationFilename = fc.getInitParameter(CONFIGURATION_FILE_PARAM); + + configurationFilename = fc.getServletContext().getRealPath(configurationFilename); + + if (configurationFilename == null || !new File(configurationFilename).exists()) { + throw new ServletException( + "[ESAPI WAF] Could not find configuration file at resolved path: " + configurationFilename); + } + + /* + * Find out polling time from a parameter. If none is provided, use the + * default (10 seconds). + */ + + String sPollingTime = fc.getInitParameter(POLLING_TIME_PARAM); + + if (sPollingTime != null) { + pollingTime = Long.parseLong(sPollingTime); + } else { + pollingTime = DEFAULT_POLLING_TIME; + } + + /* + * Open up configuration file and populate the AppGuardian configuration + * object. + */ + + FileInputStream inputStream = null; + + try { + String webRootDir = fc.getServletContext().getRealPath("/"); + inputStream = new FileInputStream(configurationFilename); + appGuardConfig = ConfigurationParser.readConfigurationFile(inputStream, webRootDir); + lastConfigReadTime = System.currentTimeMillis(); + } catch (FileNotFoundException e) { + throw new ServletException(e); + } catch (ConfigurationException e) { + throw new ServletException(e); + } finally { + if (inputStream != null) { + try { + inputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + + /** + * This is the where the main interception and rule-checking logic of the + * WAF resides. + */ + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) + throws IOException, ServletException { + + /* + * Check to see if polling time has elapsed. If it has, that means we + * should check to see if the config file has been changed. If it has, + * then re-read it. + * + * // TODO: Any reason this logic shouldn't be moved into a polling + * thread class? + */ + + if ((System.currentTimeMillis() - lastConfigReadTime) > pollingTime) { + File f = new File(configurationFilename); + long lastModified = f.lastModified(); + if (lastModified > lastConfigReadTime) { + /* + * The file has been altered since it was read in the last time. + * Must re-read it. + */ + logger.debug(Logger.EVENT_SUCCESS, ">> Re-reading WAF policy"); + init(fc); + } + } + + logger.debug(Logger.EVENT_SUCCESS, ">>In WAF doFilter"); + + HttpServletRequest httpRequest = (HttpServletRequest) servletRequest; + HttpServletResponse httpResponse = (HttpServletResponse) servletResponse; + + InterceptingHTTPServletRequest request = null; + InterceptingHTTPServletResponse response = null; + + /* + * First thing to do is create the InterceptingHTTPServletResponse, + * since we'll need that possibly before the + * InterceptingHTTPServletRequest. + * + * The normal HttpRequest-type objects will suffice us until we get to + * stage 2. + * + * 1st argument = the response to base the instance on 2nd argument = + * should we bother intercepting the egress response? 3rd argument = + * cookie rules because thats where they mostly get acted on + */ + + if (appGuardConfig.getCookieRules().size() + appGuardConfig.getBeforeResponseRules().size() > 0) { + response = new InterceptingHTTPServletResponse(httpResponse, true, appGuardConfig.getCookieRules()); + } + + /* + * Stage 1: Rules that do not need the request body. + */ + logger.debug(Logger.EVENT_SUCCESS, ">> Starting stage 1"); + + List rules = this.appGuardConfig.getBeforeBodyRules(); + + for (int i = 0; i < rules.size(); i++) { + + Rule rule = rules.get(i); + logger.debug(Logger.EVENT_SUCCESS, " Applying BEFORE rule: " + rule.getClass().getName()); + + /* + * The rules execute in check(). The check() method will also log. + * All we have to do is decide what other actions to take. + */ + Action action = rule.check(httpRequest, response, httpResponse); + + if (action.isActionNecessary()) { + + if (action instanceof BlockAction) { + if (response != null) { + response.setStatus(appGuardConfig.getDefaultResponseCode()); + } else { + httpResponse.setStatus(appGuardConfig.getDefaultResponseCode()); + } + return; + + } else if (action instanceof RedirectAction) { + sendRedirect(response, httpResponse, ((RedirectAction) action).getRedirectURL()); + return; + + } else if (action instanceof DefaultAction) { + + switch (AppGuardianConfiguration.DEFAULT_FAIL_ACTION) { + case AppGuardianConfiguration.BLOCK: + if (response != null) { + response.setStatus(appGuardConfig.getDefaultResponseCode()); + } else { + httpResponse.setStatus(appGuardConfig.getDefaultResponseCode()); + } + return; + + case AppGuardianConfiguration.REDIRECT: + sendRedirect(response, httpResponse); + return; + } + } + } + } + + /* + * Create the InterceptingHTTPServletRequest. + */ + + try { + request = new InterceptingHTTPServletRequest((HttpServletRequest) servletRequest); + } catch (FileUploadException fue) { + logger.error(Logger.EVENT_SUCCESS, "Error Wrapping Request", fue); + } + + /* + * Stage 2: After the body has been read, but before the the application + * has gotten it. + */ + logger.debug(Logger.EVENT_SUCCESS, ">> Starting Stage 2"); + + rules = this.appGuardConfig.getAfterBodyRules(); + + for (int i = 0; i < rules.size(); i++) { + + Rule rule = rules.get(i); + logger.debug(Logger.EVENT_SUCCESS, " Applying BEFORE CHAIN rule: " + rule.getClass().getName()); + + /* + * The rules execute in check(). The check() method will take care + * of logging. All we have to do is decide what other actions to + * take. + */ + Action action = rule.check(request, response, httpResponse); + + if (action.isActionNecessary()) { + + if (action instanceof BlockAction) { + if (response != null) { + response.setStatus(appGuardConfig.getDefaultResponseCode()); + } else { + httpResponse.setStatus(appGuardConfig.getDefaultResponseCode()); + } + return; + + } else if (action instanceof RedirectAction) { + sendRedirect(response, httpResponse, ((RedirectAction) action).getRedirectURL()); + return; + + } else if (action instanceof DefaultAction) { + + switch (AppGuardianConfiguration.DEFAULT_FAIL_ACTION) { + case AppGuardianConfiguration.BLOCK: + if (response != null) { + response.setStatus(appGuardConfig.getDefaultResponseCode()); + } else { + httpResponse.setStatus(appGuardConfig.getDefaultResponseCode()); + } + return; + + case AppGuardianConfiguration.REDIRECT: + sendRedirect(response, httpResponse); + return; + } + } + } + } + + /* + * In between stages 2 and 3 is the application's processing of the + * input. + */ + logger.debug(Logger.EVENT_SUCCESS, ">> Calling the FilterChain: " + chain); + chain.doFilter(request, response != null ? response : httpResponse); + + /* + * Stage 3: Before the response has been sent back to the user. + */ + logger.debug(Logger.EVENT_SUCCESS, ">> Starting Stage 3"); + + rules = this.appGuardConfig.getBeforeResponseRules(); + + for (int i = 0; i < rules.size(); i++) { + + Rule rule = rules.get(i); + logger.debug(Logger.EVENT_SUCCESS, " Applying AFTER CHAIN rule: " + rule.getClass().getName()); + + /* + * The rules execute in check(). The check() method will also log. + * All we have to do is decide what other actions to take. + */ + Action action = rule.check(request, response, httpResponse); + + if (action.isActionNecessary()) { + + if (action instanceof BlockAction) { + if (response != null) { + response.setStatus(appGuardConfig.getDefaultResponseCode()); + } else { + httpResponse.setStatus(appGuardConfig.getDefaultResponseCode()); + } + return; + + } else if (action instanceof RedirectAction) { + sendRedirect(response, httpResponse, ((RedirectAction) action).getRedirectURL()); + return; + + } else if (action instanceof DefaultAction) { + + switch (AppGuardianConfiguration.DEFAULT_FAIL_ACTION) { + case AppGuardianConfiguration.BLOCK: + if (response != null) { + response.setStatus(appGuardConfig.getDefaultResponseCode()); + } else { + httpResponse.setStatus(appGuardConfig.getDefaultResponseCode()); + } + return; + + case AppGuardianConfiguration.REDIRECT: + sendRedirect(response, httpResponse); + return; + } + } + } + } + + /* + * Now that we've run our last set of rules we can allow the response to + * go through if we were intercepting. + */ + + if (response != null) { + logger.debug(Logger.EVENT_SUCCESS, ">>> committing reponse"); + response.commit(); + } + } + + /* + * Utility method to send HTTP redirects that automatically determines which + * response class to use. + */ + private void sendRedirect(InterceptingHTTPServletResponse response, HttpServletResponse httpResponse, + String redirectURL) throws IOException { + + if (response != null) { // if we've been buffering everything we clean + // it all out before sending back. + response.reset(); + response.resetBuffer(); + response.sendRedirect(redirectURL); + response.commit(); + } else { + httpResponse.sendRedirect(redirectURL); + } + + } + + public void destroy() { + /* + * Any cleanup necessary? + */ + } + + private void sendRedirect(InterceptingHTTPServletResponse response, HttpServletResponse httpResponse) + throws IOException { + /* + * [chrisisbeef] - commented out as this is not currently used. Minor + * performance tweak. String finalJavaScript = + * AppGuardianConfiguration.JAVASCRIPT_REDIRECT; finalJavaScript = + * finalJavaScript.replaceAll(AppGuardianConfiguration. + * JAVASCRIPT_TARGET_TOKEN, appGuardConfig.getDefaultErrorPage()); + */ + + if (response != null) { + response.reset(); + response.resetBuffer(); + /* + * response.setStatus(appGuardConfig.getDefaultResponseCode()); + * response.getOutputStream().write(finalJavaScript.getBytes()); + */ + response.sendRedirect(appGuardConfig.getDefaultErrorPage()); + + } else { + if (!httpResponse.isCommitted()) { + httpResponse.sendRedirect(appGuardConfig.getDefaultErrorPage()); + } else { + /* + * Can't send redirect because response is already committed. + * I'm not sure how this could happen, but I didn't want to + * cause IOExceptions in case if it ever does. + */ + } + + } + } + +} diff --git a/src/main/java/org/owasp/esapi/waf/actions/Action.java b/src/main/java/org/owasp/esapi/waf/actions/Action.java new file mode 100644 index 000000000..46db8e350 --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/actions/Action.java @@ -0,0 +1,45 @@ +/** + * 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) 2009 - 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 2009 + */ +package org.owasp.esapi.waf.actions; + +/** + * The base class indicating what is to be done after a rule executes. + * + * @author Arshan Dabirsiaghi + * @see org.owasp.esapi.waf.rules.Rule + */ +public abstract class Action { + + protected boolean failed = true; + protected boolean actionNecessary = true; + + public void setFailed(boolean didFail) { + failed = didFail; + } + + public boolean failedRule() { + return failed; + } + + public boolean isActionNecessary() { + return actionNecessary; + } + + public void setActionNecessary(boolean b) { + this.actionNecessary = b; + + } +} diff --git a/src/main/java/org/owasp/esapi/waf/actions/BlockAction.java b/src/main/java/org/owasp/esapi/waf/actions/BlockAction.java new file mode 100644 index 000000000..a9cf60fc8 --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/actions/BlockAction.java @@ -0,0 +1,35 @@ +/** + * 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) 2009 - 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 2009 + */ +package org.owasp.esapi.waf.actions; + +/** + * The class that indicates the request processing should be halted and that a blank response + * should be returned. + * + * @author Arshan Dabirsiaghi + */ +public class BlockAction extends Action { + + public boolean failedRule() { + return true; + } + + + public boolean isActionNecessary() { + return true; + } + +} diff --git a/src/main/java/org/owasp/esapi/waf/actions/DefaultAction.java b/src/main/java/org/owasp/esapi/waf/actions/DefaultAction.java new file mode 100644 index 000000000..7aad503fa --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/actions/DefaultAction.java @@ -0,0 +1,34 @@ +/** + * 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) 2009 - 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 2009 + */ +package org.owasp.esapi.waf.actions; + +/** + * The class that indicates the default action as indicated by the policy file + * should be executed. + * + * @author Arshan Dabirsiaghi + */ +public class DefaultAction extends Action { + + public boolean failedRule() { + return true; + } + + public boolean isActionNecessary() { + return true; + } + +} diff --git a/src/main/java/org/owasp/esapi/waf/actions/DoNothingAction.java b/src/main/java/org/owasp/esapi/waf/actions/DoNothingAction.java new file mode 100644 index 000000000..70d5970f2 --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/actions/DoNothingAction.java @@ -0,0 +1,34 @@ +/** + * 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) 2009 - 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 2009 + */ +package org.owasp.esapi.waf.actions; + +/** + * The class that indicates that no further action is necessary. + * + * @author Arshan Dabirsiaghi + */ +public class DoNothingAction extends Action { + + public boolean failedRule() { + return this.failed; + } + + + public boolean isActionNecessary() { + return false; + } + +} diff --git a/src/main/java/org/owasp/esapi/waf/actions/RedirectAction.java b/src/main/java/org/owasp/esapi/waf/actions/RedirectAction.java new file mode 100644 index 000000000..b16fa4e64 --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/actions/RedirectAction.java @@ -0,0 +1,39 @@ +/** + * 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) 2009 - 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 2009 + */ +package org.owasp.esapi.waf.actions; + +/** + * The class that indicates the user should be redirected to another location. + * + * @author Arshan Dabirsiaghi + */ +public class RedirectAction extends Action { + + private String url = null; + + /* + * Setting this overrides the default value read in the config file. + */ + public void setRedirectURL(String s) { + this.url = s; + } + + public String getRedirectURL() { + return this.url; + } + + +} diff --git a/src/main/java/org/owasp/esapi/waf/actions/package.html b/src/main/java/org/owasp/esapi/waf/actions/package.html new file mode 100644 index 000000000..4fee1e14a --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/actions/package.html @@ -0,0 +1,11 @@ + + + + + + + +This package contains the Action objects that are executed after a Rule subclass executes. + + + diff --git a/src/main/java/org/owasp/esapi/waf/configuration/AppGuardianConfiguration.java b/src/main/java/org/owasp/esapi/waf/configuration/AppGuardianConfiguration.java new file mode 100644 index 000000000..25eb24847 --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/configuration/AppGuardianConfiguration.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) 2009 - 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 2009 + */ +package org.owasp.esapi.waf.configuration; + +import java.util.ArrayList; +import java.util.List; + +import org.owasp.esapi.waf.rules.Rule; + +/** + * This class is the object model of the policy file. Also holds a number of constants + * used throughout the WAF. + * + * @author Arshan Dabirsiaghi + * + */ +public class AppGuardianConfiguration { + + /* + * Fail modes (BLOCK blocks and logs the request, DONT_BLOCK simply logs) + */ + public static final int LOG = 0; + public static final int REDIRECT = 1; + public static final int BLOCK = 2; + + /* + * The operators. + */ + public static final int OPERATOR_EQ = 0; + public static final int OPERATOR_CONTAINS = 1; + public static final int OPERATOR_IN_LIST = 2; + public static final int OPERATOR_EXISTS = 3; + + + /* + * Default settings. + */ + public static int DEFAULT_FAIL_ACTION = LOG; + + // TODO: use UTF-8 + public static String DEFAULT_CHARACTER_ENCODING = "ISO-8859-1"; + public static String DEFAULT_CONTENT_TYPE = "text/html; charset=" + DEFAULT_CHARACTER_ENCODING; + + /* + * The JavaScript to redirect users to the default error page. Have + * to use this because response.sendRedirect() can't have an arbitrary + * response code and that is a requirement. + */ + public static final String JAVASCRIPT_TARGET_TOKEN = "##1##"; + public static final String JAVASCRIPT_REDIRECT = ""; + + /* + * Fail response settings. + */ + private String defaultErrorPage; + private int defaultResponseCode; + + private boolean forceHttpOnlyFlagToSession = false; + private boolean forceSecureFlagToSession = false; + + private String sessionCookieName; + + public String getSessionCookieName() { + return sessionCookieName; + } + + public void setSessionCookieName(String sessionCookieName) { + this.sessionCookieName = sessionCookieName; + } + + /* + * The object-level rules encapsulated by the stage in which they are executed. + */ + private List beforeBodyRules; + private List afterBodyRules; + private List beforeResponseRules; + private List cookieRules; + + public AppGuardianConfiguration() { + beforeBodyRules = new ArrayList(); + afterBodyRules = new ArrayList(); + beforeResponseRules = new ArrayList(); + cookieRules = new ArrayList(); + } + + public String getDefaultErrorPage() { + return defaultErrorPage; + } + + public void setDefaultErrorPage(String defaultErrorPage) { + this.defaultErrorPage = defaultErrorPage; + } + + public int getDefaultResponseCode() { + return defaultResponseCode; + } + + public void setDefaultResponseCode(int defaultResponseCode) { + this.defaultResponseCode = defaultResponseCode; + } + + + public List getBeforeBodyRules() { + return beforeBodyRules; + } + + public List getAfterBodyRules() { + return afterBodyRules; + } + + public List getBeforeResponseRules() { + return beforeResponseRules; + } + + public List getCookieRules() { + return cookieRules; + } + + public void addBeforeBodyRule(Rule r) { + beforeBodyRules.add(r); + } + + public void addAfterBodyRule(Rule r) { + afterBodyRules.add(r); + } + + public void addBeforeResponseRule(Rule r) { + beforeResponseRules.add(r); + } + + public void addCookieRule(Rule r) { + cookieRules.add(r); + } + + public void setApplyHTTPOnlyFlagToSessionCookie(boolean shouldApply) { + forceHttpOnlyFlagToSession = shouldApply; + } + + public void setApplySecureFlagToSessionCookie(boolean shouldApply) { + forceSecureFlagToSession = shouldApply; + } + + public boolean isUsingHttpOnlyFlagOnSessionCookie() { + return forceHttpOnlyFlagToSession; + } + + public boolean isUsingSecureFlagOnSessionCookie() { + return forceSecureFlagToSession; + } + + public String toString() { + StringBuilder sb = new StringBuilder( "WAF Configuration\n" ); + sb.append( "Before body rules:\n" ); + for ( Rule rule : beforeBodyRules ) sb.append( " " + rule.toString() + "\n" ); + sb.append( "After body rules:\n" ); + for ( Rule rule : afterBodyRules ) sb.append( " " + rule.toString() + "\n" ); + sb.append( "Before response rules:\n" ); + for ( Rule rule : beforeResponseRules ) sb.append( " " + rule.toString() + "\n" ); + sb.append( "Cookie rules:\n" ); + for ( Rule rule : cookieRules ) sb.append( " " + rule.toString() + "\n" ); + return sb.toString(); + } +} diff --git a/src/main/java/org/owasp/esapi/waf/configuration/ConfigurationParser.java b/src/main/java/org/owasp/esapi/waf/configuration/ConfigurationParser.java new file mode 100644 index 000000000..b5474c460 --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/configuration/ConfigurationParser.java @@ -0,0 +1,596 @@ +/** + * 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) 2009 - 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 2009 + */ +package org.owasp.esapi.waf.configuration; + +import java.io.FileNotFoundException; +import java.io.IOException; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; + +import nu.xom.Builder; +import nu.xom.Document; +import nu.xom.Element; +import nu.xom.Elements; +import nu.xom.ParsingException; +import nu.xom.ValidityException; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.waf.ConfigurationException; +import org.owasp.esapi.waf.rules.AddHTTPOnlyFlagRule; +import org.owasp.esapi.waf.rules.AddHeaderRule; +import org.owasp.esapi.waf.rules.AddSecureFlagRule; +import org.owasp.esapi.waf.rules.AuthenticatedRule; +import org.owasp.esapi.waf.rules.BeanShellRule; +import org.owasp.esapi.waf.rules.DetectOutboundContentRule; +import org.owasp.esapi.waf.rules.EnforceHTTPSRule; +import org.owasp.esapi.waf.rules.HTTPMethodRule; +import org.owasp.esapi.waf.rules.IPRule; +import org.owasp.esapi.waf.rules.MustMatchRule; +import org.owasp.esapi.waf.rules.PathExtensionRule; +import org.owasp.esapi.waf.rules.ReplaceContentRule; +import org.owasp.esapi.waf.rules.RestrictContentTypeRule; +import org.owasp.esapi.waf.rules.RestrictUserAgentRule; +import org.owasp.esapi.waf.rules.SimpleVirtualPatchRule; + +import bsh.EvalError; + +/** + * + * The class used to turn a policy file's contents into an object model. + * + * @author Arshan Dabirsiaghi + * @see org.owasp.esapi.waf.configuration.AppGuardianConfiguration + */ +public class ConfigurationParser { + + private static final String REGEX = "regex"; + private static final String DEFAULT_PATH_APPLY_ALL = ".*"; + private static final int DEFAULT_RESPONSE_CODE = 403; + private static final String DEFAULT_SESSION_COOKIE; + + static { + String sessionIdName = null; + try { + sessionIdName = ESAPI.securityConfiguration().getHttpSessionIdName(); + } catch (Throwable t) { + sessionIdName = "JSESSIONID"; // If all else fails... + } + DEFAULT_SESSION_COOKIE = sessionIdName; + } + + private static final String[] STAGES = { + "before-request-body", + "after-request-body", + "before-response" + }; + + public static AppGuardianConfiguration readConfigurationFile(InputStream stream, String webRootDir) throws ConfigurationException { + + AppGuardianConfiguration config = new AppGuardianConfiguration(); + + Builder parser = new Builder(); + Document doc; + Element root; + + try { + + doc = parser.build(stream); + root = doc.getRootElement(); + + Element settingsRoot = root.getFirstChildElement("settings"); + Element authNRoot = root.getFirstChildElement("authentication-rules"); + Element authZRoot = root.getFirstChildElement("authorization-rules"); + Element urlRoot = root.getFirstChildElement("url-rules"); + Element headerRoot = root.getFirstChildElement("header-rules"); + Element customRulesRoot = root.getFirstChildElement("custom-rules");; + Element virtualPatchesRoot = root.getFirstChildElement("virtual-patches"); + Element outboundRoot = root.getFirstChildElement("outbound-rules"); + Element beanShellRoot = root.getFirstChildElement("bean-shell-rules"); + + + /** + * Parse the 'settings' section. + */ + if ( settingsRoot == null ) { + throw new ConfigurationException("", "The section is required"); + } else if ( settingsRoot != null ) { + + + try { + String sessionCookieName = settingsRoot.getFirstChildElement("session-cookie-name").getValue(); + if ( ! "".equals(sessionCookieName) ) { + config.setSessionCookieName(sessionCookieName); + } + } catch (NullPointerException npe) { + config.setSessionCookieName(DEFAULT_SESSION_COOKIE); + } + + String mode = settingsRoot.getFirstChildElement("mode").getValue(); + + if ( "block".equals(mode.toLowerCase() ) ) { + AppGuardianConfiguration.DEFAULT_FAIL_ACTION = AppGuardianConfiguration.BLOCK; + } else if ( "redirect".equals(mode.toLowerCase() ) ){ + AppGuardianConfiguration.DEFAULT_FAIL_ACTION = AppGuardianConfiguration.REDIRECT; + } else { + AppGuardianConfiguration.DEFAULT_FAIL_ACTION = AppGuardianConfiguration.LOG; + } + + Element errorHandlingRoot = settingsRoot.getFirstChildElement("error-handling"); + + config.setDefaultErrorPage( errorHandlingRoot.getFirstChildElement("default-redirect-page").getValue() ); + + try { + config.setDefaultResponseCode( Integer.parseInt(errorHandlingRoot.getFirstChildElement("block-status").getValue()) ); + } catch (Exception e) { + config.setDefaultResponseCode( DEFAULT_RESPONSE_CODE ); + } + } + + /** + * Parse the 'authentication-rules' section if they have one. + */ + if ( authNRoot != null ) { + String key = authNRoot.getAttributeValue("key"); + String path = authNRoot.getAttributeValue("path"); + String id = authNRoot.getAttributeValue("id"); + + if ( path != null && key != null ) { + config.addBeforeBodyRule(new AuthenticatedRule(id,key,Pattern.compile(path),getExceptionsFromElement(authNRoot))); + } else if ( key != null ) { + config.addBeforeBodyRule(new AuthenticatedRule(id,key,null,getExceptionsFromElement(authNRoot))); + } else { + throw new ConfigurationException("","The rule requires a 'key' attribute"); + } + } + + /** + * Parse 'authorization-rules' section if they have one. + */ + + if ( authZRoot != null ) { + + Elements restrictNodes = authZRoot.getChildElements("restrict-source-ip"); + + for(int i=0;i exceptions = getExceptionsFromElement(e); + + config.addBeforeBodyRule( new EnforceHTTPSRule(id, Pattern.compile(path), exceptions, action) ); + } + + } + + if ( headerRoot != null ) { + + Elements restrictContentTypes = headerRoot.getChildElements("restrict-content-type"); + Elements restrictUserAgents = headerRoot.getChildElements("restrict-user-agent"); + + for(int i=0;i rules. This could be used to add: + * - X-I-DONT-WANT-TO-BE-FRAMED + * - Caching prevention headers + * - Custom application headers + */ + + Elements addHeaderNodes = outboundRoot.getChildElements("add-header"); + + for(int i=0;i rules that allow + * us to add the HTTPOnly flag to cookies, both + * custom and app server. + */ + Elements addHTTPOnlyFlagNodes = outboundRoot.getChildElements("add-http-only-flag"); + + for(int i=0;i patterns = new ArrayList(); + + for(int j=0;j rules that allow + * us to add the secure flag to cookies, both + * custom and app server. + */ + Elements addSecureFlagNodes = outboundRoot.getChildElements("add-secure-flag"); + + for(int i=0;i patterns = new ArrayList(); + + for(int j=0;j rules must contain a 'pattern' attribute"); + } else if ( contentType == null ) { + throw new ConfigurationException("", " rules must contain a 'content-type' attribute"); + } + + DetectOutboundContentRule docr = new DetectOutboundContentRule( + id, + Pattern.compile(contentType), + Pattern.compile(token,Pattern.DOTALL), + path != null ? Pattern.compile(path) : null); + + config.addBeforeResponseRule(docr); + + } + + } + + /** + * Parse the 'bean-shell-rules' section. + */ + + if ( beanShellRoot != null ) { + + Elements beanShellRules = beanShellRoot.getChildElements("bean-shell-script"); + + for (int i=0;i getExceptionsFromElement(Element root) { + Elements exceptions = root.getChildElements("path-exception"); + ArrayList exceptionList = new ArrayList(); + + for(int i=0;i + + + + + + +This package contains the both the configuration object model and the +utility class to create that object model from an existing policy file. + + + diff --git a/src/main/java/org/owasp/esapi/waf/internal/InterceptingHTTPServletRequest.java b/src/main/java/org/owasp/esapi/waf/internal/InterceptingHTTPServletRequest.java new file mode 100644 index 000000000..8c4c2b09f --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/internal/InterceptingHTTPServletRequest.java @@ -0,0 +1,209 @@ +/** + * 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) 2009 - 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 2009 + */ +package org.owasp.esapi.waf.internal; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.RandomAccessFile; +import java.util.Enumeration; +import java.util.Vector; + +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; + +import org.apache.commons.fileupload.FileItemIterator; +import org.apache.commons.fileupload.FileItemStream; +import org.apache.commons.fileupload.FileUploadException; +import org.apache.commons.fileupload.servlet.ServletFileUpload; +import org.apache.commons.fileupload.util.Streams; + +/** + * The wrapper for the HttpServletRequest object which will be passed to the application + * being protected by the WAF. It contains logic for parsing multipart parameters out of + * the request and provided downstream application logic a way of accessing it like it + * hasn't been touched. + * + * @author Arshan Dabirsiaghi + * + */ +public class InterceptingHTTPServletRequest extends HttpServletRequestWrapper { + + private Vector allParameters; + private Vector allParameterNames; + private static int CHUNKED_BUFFER_SIZE = 1024; + + private boolean isMultipart = false; + private RandomAccessFile requestBody; + private RAFInputStream is; + + public ServletInputStream getInputStream() throws IOException { + + if ( isMultipart ) { + return is; + } else { + return super.getInputStream(); + } + + } + + public BufferedReader getReader() throws IOException { + String enc = getCharacterEncoding(); + if(enc == null) enc = "UTF-8"; + return new BufferedReader(new InputStreamReader(getInputStream(), enc)); + } + + public InterceptingHTTPServletRequest(HttpServletRequest request) throws FileUploadException, IOException { + + super(request); + + allParameters = new Vector(); + allParameterNames = new Vector(); + + + /* + * Get all the regular parameters. + */ + + Enumeration e = request.getParameterNames(); + + while(e.hasMoreElements()) { + String param = (String)e.nextElement(); + allParameters.add(new Parameter(param,request.getParameter(param),false)); + allParameterNames.add(param); + } + + + /* + * Get all the multipart fields. + */ + + isMultipart = ServletFileUpload.isMultipartContent(request); + + if ( isMultipart ) { + + requestBody = new RandomAccessFile( File.createTempFile("oew","mpc"), "rw"); + + byte buffer[] = new byte[CHUNKED_BUFFER_SIZE]; + + long size = 0; + int len = 0; + + while ( len != -1 && size <= Integer.MAX_VALUE) { + len = request.getInputStream().read(buffer, 0, CHUNKED_BUFFER_SIZE); + if ( len != -1 ) { + size += len; + requestBody.write(buffer,0,len); + } + } + + is = new RAFInputStream(requestBody); + + ServletFileUpload sfu = new ServletFileUpload(); + FileItemIterator iter = sfu.getItemIterator(this); + + while(iter.hasNext()) { + FileItemStream item = iter.next(); + String name = item.getFieldName(); + InputStream stream = item.openStream(); + + /* + * If this is a regular form field, add it to our + * parameter collection. + */ + + if (item.isFormField()) { + + String value = Streams.asString(stream); + + allParameters.add(new Parameter(name,value,true)); + allParameterNames.add(name); + + } else { + /* + * This is a multipart content that is not a + * regular form field. Nothing to do here. + */ + + } + + } + + requestBody.seek(0); + + } + + } + + public String getDictionaryParameter(String s) { + + for(int i=0;ihttp://www.owasp.org/index.php/ESAPI. + * + * Copyright (c) 2009 - 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 2009 + */ +package org.owasp.esapi.waf.internal; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.List; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpServletResponseWrapper; + +import org.owasp.esapi.waf.rules.AddHTTPOnlyFlagRule; +import org.owasp.esapi.waf.rules.AddSecureFlagRule; +import org.owasp.esapi.waf.rules.Rule; + +/** + * The wrapper for the HttpServletResponse object which will be passed to the application + * being protected by the WAF. It contains logic for the response building API in order + * to allow the WAF rules regarding responses to work. Much of the work is delegated to + * other classes, especially InterceptingServletOutputStream + * + * @author Arshan Dabirsiaghi + * + */ +public class InterceptingHTTPServletResponse extends HttpServletResponseWrapper { + + private InterceptingPrintWriter ipw; + private InterceptingServletOutputStream isos; + private String contentType; + + private List addSecureFlagRules = null; + private List addHTTPOnlyFlagRules = null; + private boolean alreadyCalledWriter = false; + private boolean alreadyCalledOutputStream = false; + + public InterceptingHTTPServletResponse(HttpServletResponse response, boolean buffering, List cookieRules) throws IOException { + + super(response); + + this.contentType = response.getContentType(); + + this.isos = new InterceptingServletOutputStream(response.getOutputStream(), buffering); + this.ipw = new InterceptingPrintWriter(new PrintWriter(isos)); + + addSecureFlagRules = new ArrayList(); + addHTTPOnlyFlagRules = new ArrayList(); + + for(int i=0;i=[; =][; expires=][; + // domain=][; path=][; secure][;HttpOnly + String header = name + "=" + value; + + if ( ! isTemporary ) { + header += "; Max-Age=" + maxAge; + } + + if (domain != null) { + header += "; Domain=" + domain; + } + if (path != null) { + header += "; Path=" + path; + } + + if ( secure ) { + header += "; Secure"; + } + + if (httpOnly) { + header += "; HttpOnly"; + } + + return header; + } + +} diff --git a/src/main/java/org/owasp/esapi/waf/internal/InterceptingPrintWriter.java b/src/main/java/org/owasp/esapi/waf/internal/InterceptingPrintWriter.java new file mode 100644 index 000000000..57200e7a4 --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/internal/InterceptingPrintWriter.java @@ -0,0 +1,182 @@ +/** + * 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) 2009 - 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 2009 + */ +package org.owasp.esapi.waf.internal; + +import java.io.PrintWriter; +import java.io.Writer; +import java.util.Locale; + +/** + * The PrintWriter needed to buffer outbound data generated by the application + * being protected by the WAF. Currently no logic is needed here right now due + * to the WAF things have been architected in the main file, + * InterceptingHTTPServletResponse. + * + * @author Arshan Dabirsiaghi + * @see org.owasp.esapi.waf.internal.InterceptingHTTPServletResponse + */ +public class InterceptingPrintWriter extends PrintWriter { + + public InterceptingPrintWriter(Writer out) { + super(out); + } + + public PrintWriter append(char c) { + return super.append(c); + } + + public PrintWriter append(CharSequence csq, int start, int end) { + return super.append(csq, start, end); + } + + public PrintWriter append(CharSequence csq) { + return super.append(csq); + } + + public boolean checkError() { + return super.checkError(); + } + +// Java 1.6 only +// protected void clearError() { +// super.clearError(); +// } + + public void close() { + super.close(); + } + + public void flush() { + super.flush(); + } + + public PrintWriter format(Locale l, String format, Object... args) { + return super.format(l, format, args); + } + + public PrintWriter format(String format, Object... args) { + return super.format(format, args); + } + + public void print(boolean b) { + super.print(b); + } + + public void print(char c) { + super.print(c); + } + + public void print(char[] s) { + super.print(s); + } + + public void print(double d) { + super.print(d); + } + + public void print(float f) { + super.print(f); + } + + public void print(int i) { + super.print(i); + } + + public void print(long l) { + super.print(l); + } + + public void print(Object obj) { + super.print(obj); + } + + public void print(String s) { + super.print(s); + } + + public PrintWriter printf(Locale l, String format, Object... args) { + return super.printf(l, format, args); + } + + public PrintWriter printf(String format, Object... args) { + return super.printf(format, args); + } + + public void println() { + super.println(); + } + + public void println(boolean x) { + super.println(x); + } + + public void println(char x) { + super.println(x); + } + + public void println(char[] x) { + super.println(x); + } + + public void println(double x) { + super.println(x); + } + + public void println(float x) { + super.println(x); + } + + public void println(int x) { + super.println(x); + } + + public void println(long x) { + super.println(x); + } + + public void println(Object x) { + super.println(x); + } + + public void println(String x) { + super.println(x); + } + + protected void setError() { + super.setError(); + } + + public void write(char[] buf, int off, int len) { + super.write(buf, off, len); + } + + public void write(char[] buf) { + super.write(buf); + } + + public void write(int c) { + super.write(c); + } + + public void write(String s, int off, int len) { + super.write(s, off, len); + } + + public void write(String s) { + super.write(s); + } + +} diff --git a/src/main/java/org/owasp/esapi/waf/internal/InterceptingServletOutputStream.java b/src/main/java/org/owasp/esapi/waf/internal/InterceptingServletOutputStream.java new file mode 100644 index 000000000..47fd19fe9 --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/internal/InterceptingServletOutputStream.java @@ -0,0 +1,175 @@ +/** + * 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) 2009 - 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 2009 + */ +package org.owasp.esapi.waf.internal; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; + +import javax.servlet.ServletOutputStream; +import javax.servlet.WriteListener; + +/** + * This class was inspired by ModSecurity for Java by Ivan Ristic. We hook + * the response stream and queue up all outbound data so that we can apply + * egress rules. For efficiency, we decide off the bat if we need to buffer + * responses to accomplish any of the rules in the policy file. + * + * If not, we just forward everything through, otherwise we write data to our + * byte stream that we will eventually forward en totale to the user agent. + * + * @author Arshan Dabirsiaghi + */ + +public class InterceptingServletOutputStream extends ServletOutputStream { + + private static final int FLUSH_BLOCK_SIZE = 1024; + private ServletOutputStream os; + private boolean buffering; + private boolean committed; + private boolean closed; + + private RandomAccessFile out; + + public InterceptingServletOutputStream(ServletOutputStream os, boolean buffered) throws FileNotFoundException, IOException { + super(); + this.os = os; + this.buffering = buffered; + this.committed = false; + this.closed = false; + + /* + * Creating a RandomAccessFile to keep track of output generated. I made + * the prefix and suffix small for less processing. The "oew" is intended + * to stand for "OWASP ESAPI WAF" and the "hop" for HTTP output. + */ + File tempFile= File.createTempFile("oew", ".hop"); + this.out = new RandomAccessFile (tempFile, "rw" ); + tempFile.deleteOnExit(); + + } + + public void reset() throws IOException { + out.setLength(0L); + } + + public byte[] getResponseBytes() throws IOException { + + byte[] buffer = new byte[(int) out.length()]; + out.seek(0); + out.read(buffer, 0, (int)out.length()); + out.seek(out.length()); + return buffer; + + } + + public void setResponseBytes(byte[] responseBytes) throws IOException { + + if ( ! buffering && out.length() > 0 ) { + throw new IOException("Already committed response because not currently buffering"); + } + + out.setLength(0L); + out.write(responseBytes); + } + + public void write(int i) throws IOException { + if (!buffering) { + os.write(i); + } + out.write(i); + } + + public void write(byte[] b) throws IOException { + if (!buffering) { + os.write(b, 0, b.length); + } + out.write(b, 0, b.length); + } + + public void write(byte[] b, int off, int len) throws IOException { + if (!buffering) { + os.write(b, off, len); + } + out.write(b, off, len); + } + + public void flush() throws IOException { + + if (buffering) { + + synchronized(out) { + + out.seek(0); + + byte[] buff = new byte[FLUSH_BLOCK_SIZE]; + + for(int i=0;ihttp://www.owasp.org/index.php/ESAPI. + * + * Copyright (c) 2009 - 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 2009 + */ +package org.owasp.esapi.waf.internal; + +/** + * A simple object to represent a name=value HTTP parameter. + * + * @author Arshan Dabirsiaghi + * + */ +public class Parameter { + + private String name; + private String value; + private boolean fromMultipart; + + public Parameter(String name, String value, boolean fromMultipart) { + this.name = name; + this.value = value; + this.fromMultipart = fromMultipart; + } + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getValue() { + return value; + } + public void setValue(String value) { + this.value = value; + } + +} diff --git a/src/main/java/org/owasp/esapi/waf/internal/package.html b/src/main/java/org/owasp/esapi/waf/internal/package.html new file mode 100644 index 000000000..92d808c9f --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/internal/package.html @@ -0,0 +1,12 @@ + + + + + + + +This package contains all HTTP-related classes used internally by the WAF for the implementation +of its rules. + + + diff --git a/src/main/java/org/owasp/esapi/waf/package.html b/src/main/java/org/owasp/esapi/waf/package.html new file mode 100644 index 000000000..186c820f8 --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/package.html @@ -0,0 +1,14 @@ + + + + + + + +This package contains the ESAPI Web Application Firewall (WAF). It is an optional feature of ESAPI +that can be used with or without ESAPI's other security controls in place. It's purpose is to provide +fast virtual patching capabilities against known vulnerabilities or the enforcement of existing +security policies where possible. + + + diff --git a/src/main/java/org/owasp/esapi/waf/rules/AddHTTPOnlyFlagRule.java b/src/main/java/org/owasp/esapi/waf/rules/AddHTTPOnlyFlagRule.java new file mode 100644 index 000000000..21395cb5e --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/rules/AddHTTPOnlyFlagRule.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) 2009 - 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 2009 + */ +package org.owasp.esapi.waf.rules; + +import java.util.List; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.owasp.esapi.waf.actions.Action; +import org.owasp.esapi.waf.actions.DoNothingAction; +import org.owasp.esapi.waf.internal.InterceptingHTTPServletResponse; + +/** + * This is the Rule subclass executed for <add-http-only-flag> rules. + * @author Arshan Dabirsiaghi + * + */ +public class AddHTTPOnlyFlagRule extends Rule { + + private List name; + + public AddHTTPOnlyFlagRule(String id, List name) { + setId(id); + this.name = name; + } + + public Action check(HttpServletRequest request, + InterceptingHTTPServletResponse response, + HttpServletResponse httpResponse) { + + DoNothingAction action = new DoNothingAction(); + + return action; + } + + public boolean doesCookieMatch(String cookieName) { + + for(int i=0;ihttp://www.owasp.org/index.php/ESAPI. + * + * Copyright (c) 2009 - 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 2009 + */ +package org.owasp.esapi.waf.rules; + +import java.util.List; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.owasp.esapi.waf.actions.Action; +import org.owasp.esapi.waf.actions.DoNothingAction; +import org.owasp.esapi.waf.internal.InterceptingHTTPServletResponse; + +/** + * This is the Rule subclass executed for <add-header> rules. + * @author Arshan Dabirsiaghi + * + */ +public class AddHeaderRule extends Rule { + + private String header; + private String value; + private Pattern path; + private List exceptions; + + public AddHeaderRule(String id, String header, String value, Pattern path, List exceptions) { + setId(id); + this.header = header; + this.value = value; + this.path = path; + this.exceptions = exceptions; + } + + public Action check( + HttpServletRequest request, + InterceptingHTTPServletResponse response, + HttpServletResponse httpResponse) { + + DoNothingAction action = new DoNothingAction(); + + if ( path.matcher(request.getRequestURI()).matches() ) { + + for(int i=0;ihttp://www.owasp.org/index.php/ESAPI. + * + * Copyright (c) 2009 - 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 2009 + */ +package org.owasp.esapi.waf.rules; + +import java.util.List; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.owasp.esapi.waf.actions.Action; +import org.owasp.esapi.waf.actions.DoNothingAction; +import org.owasp.esapi.waf.internal.InterceptingHTTPServletResponse; + +/** + * This is the Rule subclass executed for <add-secure-flag> rules. + * @author Arshan Dabirsiaghi + * + */ +public class AddSecureFlagRule extends Rule { + + private List name; + + public AddSecureFlagRule(String id, List name) { + this.name = name; + setId(id); + } + + public Action check(HttpServletRequest request, + InterceptingHTTPServletResponse response, + HttpServletResponse httpResponse) { + + DoNothingAction action = new DoNothingAction(); + + return action; + } + + public boolean doesCookieMatch(String cookieName) { + + for(int i=0;ihttp://www.owasp.org/index.php/ESAPI. + * + * Copyright (c) 2009 - 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 2009 + */ +package org.owasp.esapi.waf.rules; + +import java.util.Iterator; +import java.util.List; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.owasp.esapi.waf.actions.Action; +import org.owasp.esapi.waf.actions.DefaultAction; +import org.owasp.esapi.waf.actions.DoNothingAction; +import org.owasp.esapi.waf.internal.InterceptingHTTPServletResponse; + +/** + * This is the Rule subclass executed for <authentication-rules> rules. + * @author Arshan Dabirsiaghi + * + */ +public class AuthenticatedRule extends Rule { + + private String sessionAttribute; + private Pattern path; + private List exceptions; + + public AuthenticatedRule(String id, String sessionAttribute, Pattern path, List exceptions) { + this.sessionAttribute = sessionAttribute; + this.path = path; + this.exceptions = exceptions; + setId(id); + } + + public Action check(HttpServletRequest request, + InterceptingHTTPServletResponse response, + HttpServletResponse httpResponse) { + + HttpSession session = request.getSession(); + String uri = request.getRequestURI(); + + if ( path != null && ! path.matcher(uri).matches() ) { + return new DoNothingAction(); + } + + if ( session != null && session.getAttribute(sessionAttribute) != null ) { + + return new DoNothingAction(); + + } else { /* check if it's one of the exceptions */ + + Iterator it = exceptions.iterator(); + + while(it.hasNext()) { + Object o = it.next(); + if ( o instanceof Pattern ) { + + Pattern p = (Pattern)o; + if ( p.matcher(uri).matches() ) { + return new DoNothingAction(); + } + + } else if ( o instanceof String ) { + + if ( uri.equals((String)o)) { + return new DoNothingAction(); + } + + } + } + } + + log(request, "User requested unauthenticated access to URI '" + request.getRequestURI() + "' [querystring="+request.getQueryString()+"]"); + + return new DefaultAction(); + } + +} diff --git a/src/main/java/org/owasp/esapi/waf/rules/BeanShellRule.java b/src/main/java/org/owasp/esapi/waf/rules/BeanShellRule.java new file mode 100644 index 000000000..7d0310796 --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/rules/BeanShellRule.java @@ -0,0 +1,119 @@ +/** + * 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) 2009 - 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 2009 + */ +package org.owasp.esapi.waf.rules; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.waf.actions.Action; +import org.owasp.esapi.waf.actions.DoNothingAction; +import org.owasp.esapi.waf.internal.InterceptingHTTPServletResponse; + +import bsh.EvalError; +import bsh.Interpreter; + +/** + * This is the Rule subclass executed for <bean-shell-script> rules. + * + * @author Arshan Dabirsiaghi + * + */ +public class BeanShellRule extends Rule { + + private Interpreter i; + private String script; + private Pattern path; + + public BeanShellRule(String fileLocation, String id, Pattern path) throws IOException, EvalError { + i = new Interpreter(); + i.set("logger", logger); + this.script = getFileContents(ESAPI.securityConfiguration().getResourceFile(fileLocation)); + this.id = id; + this.path = path; + } + + public Action check(HttpServletRequest request, InterceptingHTTPServletResponse response, + HttpServletResponse httpResponse) { + + /* + * Early fail: if the URL doesn't match one we're interested in. + */ + + if (path != null && !path.matcher(request.getRequestURI()).matches()) { + return new DoNothingAction(); + } + + /* + * Run the beanshell that we've already parsed and pre-compiled. + * Populate the "request" and "response" objects so the script has + * access to the same variables we do here. + */ + + try { + + Action a = null; + + i.set("action", a); + i.set("request", request); + + if (response != null) { + i.set("response", response); + } else { + i.set("response", httpResponse); + } + + i.set("session", request.getSession()); + i.eval(script); + + a = (Action) i.get("action"); + + if (a != null) { + return a; + } + + } catch (EvalError e) { + log(request, "Error running custom beanshell rule (" + id + ") - " + e.getMessage()); + } + + return new DoNothingAction(); + } + + private String getFileContents(File f) throws IOException { + StringBuffer sb = new StringBuffer(); + BufferedReader br = null; + + try { + br = new BufferedReader(new FileReader(f)); + String line; + while ((line = br.readLine()) != null) { + sb.append(line + System.getProperty("line.separator")); + } + + } finally { + if (br != null) { + br.close(); + } + } + return sb.toString(); + } +} diff --git a/src/main/java/org/owasp/esapi/waf/rules/DetectOutboundContentRule.java b/src/main/java/org/owasp/esapi/waf/rules/DetectOutboundContentRule.java new file mode 100644 index 000000000..92931fb80 --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/rules/DetectOutboundContentRule.java @@ -0,0 +1,116 @@ +/** + * 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) 2009 - 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 2009 + */ +package org.owasp.esapi.waf.rules; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.owasp.esapi.waf.actions.Action; +import org.owasp.esapi.waf.actions.DefaultAction; +import org.owasp.esapi.waf.actions.DoNothingAction; +import org.owasp.esapi.waf.configuration.AppGuardianConfiguration; +import org.owasp.esapi.waf.internal.InterceptingHTTPServletResponse; + +/** + * This is the Rule subclass executed for <detect-content> rules. + * @author Arshan Dabirsiaghi + * + */ +public class DetectOutboundContentRule extends Rule { + + private Pattern contentType; + private Pattern pattern; + private Pattern uri; + + public DetectOutboundContentRule(String id, Pattern contentType, Pattern pattern, Pattern uri) { + this.contentType = contentType; + this.pattern = pattern; + this.uri = uri; + setId(id); + } + + public Action check(HttpServletRequest request, + InterceptingHTTPServletResponse response, + HttpServletResponse httpResponse) { + + /* + * Early fail: if URI doesn't match. + */ + if ( uri != null && ! uri.matcher(request.getRequestURI()).matches() ) { + return new DoNothingAction(); + } + + /* + * Early fail: if the content type is one we'd like to search for output patterns. + */ + + String inboundContentType; + String charEnc; + + if ( response != null ) { + if ( response.getContentType() == null ) { + response.setContentType(AppGuardianConfiguration.DEFAULT_CONTENT_TYPE); + } + inboundContentType = response.getContentType(); + charEnc = response.getCharacterEncoding(); + + } else { + if ( httpResponse.getContentType() == null ) { + httpResponse.setContentType(AppGuardianConfiguration.DEFAULT_CONTENT_TYPE); + } + inboundContentType = httpResponse.getContentType(); + charEnc = httpResponse.getCharacterEncoding(); + } + + if ( contentType.matcher(inboundContentType).matches() ) { + /* + * Depending on the encoding, search through the bytes + * for the pattern. + */ + try { + + byte[] bytes = null; + + try { + bytes = response.getInterceptingServletOutputStream().getResponseBytes(); + } catch (IOException ioe) { + log(request,"Error matching pattern '" + pattern.pattern() + "', IOException encountered (possibly too large?): " + ioe.getMessage() + " (in response to URL: '" + request.getRequestURL() + "')"); + return new DoNothingAction(); // yes this is a fail open! + } + + String s = new String(bytes,charEnc); + + if ( pattern.matcher(s).matches() ) { + + log(request,"Content pattern '" + pattern.pattern() + "' was found in response to URL: '" + request.getRequestURL() + "'"); + return new DefaultAction(); + + } + + } catch (UnsupportedEncodingException uee) { + log(request,"Content pattern '" + pattern.pattern() + "' could not be found due to encoding error: " + uee.getMessage()); + } + } + + return new DoNothingAction(); + + } + +} diff --git a/src/main/java/org/owasp/esapi/waf/rules/EnforceHTTPSRule.java b/src/main/java/org/owasp/esapi/waf/rules/EnforceHTTPSRule.java new file mode 100644 index 000000000..bd31562c3 --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/rules/EnforceHTTPSRule.java @@ -0,0 +1,95 @@ +/** + * 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) 2009 - 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 2009 + */ +package org.owasp.esapi.waf.rules; + +import java.util.Iterator; +import java.util.List; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.owasp.esapi.waf.actions.Action; +import org.owasp.esapi.waf.actions.DefaultAction; +import org.owasp.esapi.waf.actions.DoNothingAction; +import org.owasp.esapi.waf.actions.RedirectAction; +import org.owasp.esapi.waf.internal.InterceptingHTTPServletResponse; + +/** + * This is the Rule subclass executed for <enforce-https> rules. + * @author Arshan Dabirsiaghi + * + */ +public class EnforceHTTPSRule extends Rule { + + private Pattern path; + private List exceptions; + private String action; + + /* + * action = [ redirect | block ] [=default (redirect will redirect to error page] + */ + + public EnforceHTTPSRule(String id, Pattern path, List exceptions, String action) { + this.path = path; + this.exceptions = exceptions; + this.action = action; + setId(id); + } + + public Action check(HttpServletRequest request, + InterceptingHTTPServletResponse response, + HttpServletResponse httpResponse) { + + if ( ! request.isSecure() ) { + + if ( path.matcher(request.getRequestURI()).matches() ) { + + Iterator it = exceptions.iterator(); + + while(it.hasNext()){ + + Object o = it.next(); + + if ( o instanceof String ) { + if ( ((String)o).equalsIgnoreCase(request.getRequestURI()) ) { + return new DoNothingAction(); + } + } else if ( o instanceof Pattern ) { + if ( ((Pattern)o).matcher(request.getRequestURI()).matches() ) { + return new DoNothingAction(); + } + } + + } + + log(request,"Insecure request to resource detected in URL: '" + request.getRequestURL() + "'"); + + if ( "redirect".equals(action) ) { + RedirectAction ra = new RedirectAction(); + ra.setRedirectURL(request.getRequestURL().toString().replaceFirst("http", "https")); + return ra; + } + + return new DefaultAction(); + + } + } + + return new DoNothingAction(); + + } +} diff --git a/src/main/java/org/owasp/esapi/waf/rules/GeneralAttackSignatureRule.java b/src/main/java/org/owasp/esapi/waf/rules/GeneralAttackSignatureRule.java new file mode 100644 index 000000000..66edec401 --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/rules/GeneralAttackSignatureRule.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) 2009 - 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 2009 + */ +package org.owasp.esapi.waf.rules; + +import java.util.Enumeration; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.owasp.esapi.waf.actions.Action; +import org.owasp.esapi.waf.actions.DefaultAction; +import org.owasp.esapi.waf.actions.DoNothingAction; +import org.owasp.esapi.waf.internal.InterceptingHTTPServletRequest; +import org.owasp.esapi.waf.internal.InterceptingHTTPServletResponse; + +/** + * This is the Rule subclass executed for <general-attack-signature> rules, which + * are not currently implemented. + * @author Arshan Dabirsiaghi + * + */ +public class GeneralAttackSignatureRule extends Rule { + + private Pattern signature; + + public GeneralAttackSignatureRule(String id, Pattern signature) { + this.signature = signature; + setId(id); + } + + public Action check(HttpServletRequest req, + InterceptingHTTPServletResponse response, + HttpServletResponse httpResponse) { + + InterceptingHTTPServletRequest request = (InterceptingHTTPServletRequest)req; + Enumeration e = request.getParameterNames(); + + while(e.hasMoreElements()) { + String param = (String)e.nextElement(); + if ( signature.matcher(request.getDictionaryParameter(param)).matches() ) { + log(request,"General attack signature detected in parameter '" + param + "' value '" + request.getDictionaryParameter(param) + "'"); + return new DefaultAction(); + } + } + + return new DoNothingAction(); + } + +} diff --git a/src/main/java/org/owasp/esapi/waf/rules/HTTPMethodRule.java b/src/main/java/org/owasp/esapi/waf/rules/HTTPMethodRule.java new file mode 100644 index 000000000..1c8e8e1dd --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/rules/HTTPMethodRule.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) 2009 - 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 2009 + */ +package org.owasp.esapi.waf.rules; + +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.owasp.esapi.waf.actions.Action; +import org.owasp.esapi.waf.actions.DefaultAction; +import org.owasp.esapi.waf.actions.DoNothingAction; +import org.owasp.esapi.waf.internal.InterceptingHTTPServletResponse; + +/** + * This is the Rule subclass executed for <restrict-method> rules. + * @author Arshan Dabirsiaghi + * + */ +public class HTTPMethodRule extends Rule { + + private Pattern allowedMethods; + private Pattern deniedMethods; + private Pattern path; + + public HTTPMethodRule(String id, Pattern allowedMethods, Pattern deniedMethods, Pattern path) { + this.allowedMethods = allowedMethods; + this.deniedMethods = deniedMethods; + this.path = path; + setId(id); + } + + public Action check(HttpServletRequest request, + InterceptingHTTPServletResponse response, + HttpServletResponse httpResponse) { + + /* + * If no path is specified, apply rule globally. + */ + String uri = request.getRequestURI(); + String method = request.getMethod(); + + if ( path == null || path.matcher(uri).matches() ) { + /* + * Order allow, deny. + */ + + if ( allowedMethods != null && allowedMethods.matcher(method).matches() ) { + return new DoNothingAction(); + } else if ( allowedMethods != null ) { + log(request,"Disallowed HTTP method '" + request.getMethod() + "' found for URL: " + request.getRequestURL()); + return new DefaultAction(); + } + + if ( deniedMethods != null && deniedMethods.matcher(method).matches() ) { + log(request,"Disallowed HTTP method '" + request.getMethod() + "' found for URL: " + request.getRequestURL()); + return new DefaultAction(); + } + + } + + return new DoNothingAction(); + } + +} diff --git a/src/main/java/org/owasp/esapi/waf/rules/IPRule.java b/src/main/java/org/owasp/esapi/waf/rules/IPRule.java new file mode 100644 index 000000000..eaa534ebe --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/rules/IPRule.java @@ -0,0 +1,79 @@ +/** + * 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) 2009 - 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 2009 + */ +package org.owasp.esapi.waf.rules; + +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.owasp.esapi.waf.actions.Action; +import org.owasp.esapi.waf.actions.DefaultAction; +import org.owasp.esapi.waf.actions.DoNothingAction; +import org.owasp.esapi.waf.internal.InterceptingHTTPServletResponse; + +/** + * This is the Rule subclass executed for <detect-source-ip> rules. + * @author Arshan Dabirsiaghi + * + */ +public class IPRule extends Rule { + + private Pattern allowedIP; + private String exactPath; + private Pattern path; + private boolean useExactPath = false; + private String ipHeader; + + public IPRule(String id, Pattern allowedIP, Pattern path, String ipHeader) { + this.allowedIP = allowedIP; + this.path = path; + this.useExactPath = false; + this.ipHeader = ipHeader; + setId(id); + } + + public IPRule(String id, Pattern allowedIP, String exactPath) { + this.path = null; + this.exactPath = exactPath; + this.useExactPath = true; + setId(id); + } + + public Action check(HttpServletRequest request, + InterceptingHTTPServletResponse response, + HttpServletResponse httpResponse) { + + String uri = request.getRequestURI(); + + if ( (!useExactPath && path.matcher(uri).matches()) || + ( useExactPath && exactPath.equals(uri)) ) { + + String sourceIP = request.getRemoteAddr() + ""; + + if ( ipHeader != null ) { + sourceIP = request.getHeader(ipHeader); + } + + if ( ! allowedIP.matcher(sourceIP).matches() ) { + log(request, "IP not allowed to access URI '" + uri + "'"); + return new DefaultAction(); + } + } + + return new DoNothingAction(); + } +} diff --git a/src/main/java/org/owasp/esapi/waf/rules/MustMatchRule.java b/src/main/java/org/owasp/esapi/waf/rules/MustMatchRule.java new file mode 100644 index 000000000..9b0c42ff5 --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/rules/MustMatchRule.java @@ -0,0 +1,336 @@ +/** + * 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) 2009 - 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 2009 + */ +package org.owasp.esapi.waf.rules; + +import java.util.Collection; +import java.util.Enumeration; +import java.util.Map; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.owasp.esapi.waf.actions.Action; +import org.owasp.esapi.waf.actions.DefaultAction; +import org.owasp.esapi.waf.actions.DoNothingAction; +import org.owasp.esapi.waf.configuration.AppGuardianConfiguration; +import org.owasp.esapi.waf.internal.InterceptingHTTPServletRequest; +import org.owasp.esapi.waf.internal.InterceptingHTTPServletResponse; + +/** + * This is the Rule subclass executed for <must-match> rules. + * @author Arshan Dabirsiaghi + * + */ +public class MustMatchRule extends Rule { + + private static final String REQUEST_PARAMETERS = "request.parameters."; + private static final String REQUEST_HEADERS = "request.headers."; + private static final String REQUEST_URI = "request.uri"; + private static final String REQUEST_URL = "request.url"; + private static final String SESSION_ATTRIBUTES = "session."; + + private Pattern path; + private String variable; + private int operator; + private String value; + + public MustMatchRule(String id, Pattern path, String variable, int operator, String value) { + this.path = path; + this.variable = variable; + this.operator = operator; + this.value = value; + setId(id); + } + + public Action check(HttpServletRequest req, + InterceptingHTTPServletResponse response, + HttpServletResponse httpResponse) { + + InterceptingHTTPServletRequest request = (InterceptingHTTPServletRequest)req; + + String uri = request.getRequestURI(); + if ( ! path.matcher(uri).matches() ) { + + return new DoNothingAction(); + + } else { + + String target = null; + + /* + * First check if we're going to be dealing with request parameters + */ + if ( variable.startsWith( REQUEST_PARAMETERS ) ) { + + if ( operator == AppGuardianConfiguration.OPERATOR_EXISTS ) { + + target = variable.substring(REQUEST_PARAMETERS.length()); + + if ( request.getParameter(target) != null ) { + return new DoNothingAction(); + } + + } else if ( operator == AppGuardianConfiguration.OPERATOR_IN_LIST ) { + + /* + * This doesn't make sense. The variable to test is a request parameter + * but the rule is looking for a List. Let the control fall through + * to the bottom where we'll return false. + */ + + } else if ( operator == AppGuardianConfiguration.OPERATOR_EQ || operator == AppGuardianConfiguration.OPERATOR_CONTAINS ) { + + /** + * Working with request parameters. If we detect + * simple regex characters, we treat it as a regex. + * Otherwise we treat it as a single parameter. + */ + target = variable.substring(REQUEST_PARAMETERS.length()); + + if ( target.contains("*") || target.contains("?") ) { + + target = target.replaceAll("*", ".*"); + Pattern p = Pattern.compile(target); + + Enumeration e = request.getParameterNames(); + + while(e.hasMoreElements()) { + String param = (String)e.nextElement(); + + if ( p.matcher(param).matches() ) { + String s = request.getParameter(param); + if ( ! RuleUtil.testValue(s, value, operator) ) { + log(request, "MustMatch rule failed (operator="+operator+"), value='" + value + "', input='" + s + "' parameter='"+param+"'"); + return new DefaultAction(); + } + } + } + + } else { + + String s = request.getParameter(target); + + if ( ! RuleUtil.testValue(s, value, operator) ) { + log(request, "MustMatch rule failed (operator="+operator+"), value='" + value + "', input='" + s + "', parameter='"+target+"'"); + return new DefaultAction(); + } + + } + } + + } else if ( variable.startsWith( REQUEST_HEADERS ) ) { + + /** + * Do the same for request headers. + */ + + if ( operator == AppGuardianConfiguration.OPERATOR_EXISTS ) { + + target = variable.substring(REQUEST_HEADERS.length()); + + if ( request.getHeader(target) != null ) { + return new DoNothingAction(); + } + + } else if ( operator == AppGuardianConfiguration.OPERATOR_IN_LIST ) { + + /* + * This doesn't make sense. The variable to test is a request header + * but the rule is looking for a List. Let the control fall through + * to the bottom where we'll return false. + */ + + } else if ( operator == AppGuardianConfiguration.OPERATOR_EQ || operator == AppGuardianConfiguration.OPERATOR_CONTAINS ) { + + target = variable.substring(REQUEST_HEADERS.length()); + + if ( target.contains("*") || target.contains("?") ) { + + target = target.replaceAll("*", ".*"); + Pattern p = Pattern.compile(target); + + Enumeration e = request.getHeaderNames(); + + while(e.hasMoreElements()) { + String header = (String)e.nextElement(); + if ( p.matcher(header).matches() ) { + String s = request.getHeader(header); + if ( ! RuleUtil.testValue(s, value, operator) ) { + log(request, "MustMatch rule failed (operator="+operator+"), value='" + value + "', input='" + s + "', header='"+header+"'"); + return new DefaultAction(); + } + } + } + + return new DoNothingAction(); + + } else { + + String s = request.getHeader(target); + + if ( s == null || ! RuleUtil.testValue(s, value, operator) ) { + log(request, "MustMatch rule failed (operator="+operator+"), value='" + value + "', input='" + s + "', header='"+target+"'"); + return new DefaultAction(); + } + + return new DoNothingAction(); + + } + + } + + } else if ( variable.startsWith(SESSION_ATTRIBUTES) ) { + + /** + * Do the same for session attributes. Can't possibly match + * ANY rule if there is no session object. + */ + if ( request.getSession(false) == null ) { + return new DefaultAction(); + } + + target = variable.substring(SESSION_ATTRIBUTES.length()+1); + + if ( operator == AppGuardianConfiguration.OPERATOR_IN_LIST ) { + + /* + * Want to check if the List/Enumeration/whatever stored + * in "target" contains the value in "value". + */ + + Object o = request.getSession(false).getAttribute(target); + + if ( o instanceof Collection ) { + if ( RuleUtil.isInList((Collection)o, value) ) { + return new DoNothingAction(); + } else { + log(request, "MustMatch rule failed - looking for value='" + value + "', in session Collection attribute '" + target + "']"); + return new DefaultAction(); + } + } else if ( o instanceof Map ) { + if ( RuleUtil.isInList((Map)o, value) ) { + return new DoNothingAction(); + } else { + log(request, "MustMatch rule failed - looking for value='" + value + "', in session Map attribute '" + target + "']"); + return new DefaultAction(); + } + } else if ( o instanceof Enumeration ) { + if ( RuleUtil.isInList((Enumeration)o, value) ) { + return new DoNothingAction(); + } else { + log(request, "MustMatch rule failed - looking for value='" + value + "', in session Enumeration attribute '" + target + "']"); + return new DefaultAction(); + } + } + + /* + * The attribute was not a common list-type of Java object s + * let the control fall through to the bottom where it will + * fail. + */ + + } else if ( operator == AppGuardianConfiguration.OPERATOR_EXISTS) { + + Object o = request.getSession(false).getAttribute(target); + + if ( o != null ) { + return new DoNothingAction(); + } else { + log(request, "MustMatch rule failed - couldn't find required session attribute='" + target + "'"); + return new DefaultAction(); + } + + } else if ( operator == AppGuardianConfiguration.OPERATOR_EQ || operator == AppGuardianConfiguration.OPERATOR_CONTAINS ) { + + if ( target.contains("*") || target.contains("?") ) { + + target = target.replaceAll("\\*", ".*"); + Pattern p = Pattern.compile(target); + + Enumeration e = request.getSession(false).getAttributeNames(); + + while(e.hasMoreElements()) { + + String attr = (String)e.nextElement(); + + if (p.matcher(attr).matches() ) { + + Object o = request.getSession(false).getAttribute(attr); + + if ( ! RuleUtil.testValue((String)o, value, operator) ) { + log(request, "MustMatch rule failed (operator="+operator+"), value='" + value + "', session attribute='" + attr + "', attribute value='"+(String)o+"'"); + return new DefaultAction(); + } else { + return new DoNothingAction(); + } + } + } + + } else { + + Object o = request.getSession(false).getAttribute(target); + + if ( ! RuleUtil.testValue((String)o, value, operator) ) { + log(request, "MustMatch rule failed (operator="+operator+"), value='" + value + "', session attribute='" + target + "', attribute value='"+(String)o+"'"); + return new DefaultAction(); + } else { + return new DoNothingAction(); + } + + } + + } + + } else if ( variable.equals( REQUEST_URI ) ) { + + if ( operator == AppGuardianConfiguration.OPERATOR_EQ || operator == AppGuardianConfiguration.OPERATOR_CONTAINS ) { + if ( RuleUtil.testValue(request.getRequestURI(), value, operator) ) { + return new DoNothingAction(); + } else { + log(request, "MustMatch rule on request URI failed (operator="+operator+"), requestURI='" + request.getRequestURI() + "', value='" + value+ "'"); + return new DefaultAction(); + } + } + + /* + * Any other operator doesn't make sense. + */ + + } else if ( variable.equals( REQUEST_URL ) ) { + + if ( operator == AppGuardianConfiguration.OPERATOR_EQ || operator == AppGuardianConfiguration.OPERATOR_CONTAINS ) { + if ( RuleUtil.testValue(request.getRequestURL().toString(), value, operator) ) { + return new DoNothingAction(); + } else { + log(request, "MustMatch rule on request URL failed (operator="+operator+"), requestURL='" + request.getRequestURL() + "', value='" + value+ "'"); + return new DefaultAction(); + } + } + + /* + * Any other operator doesn't make sense. + */ + } + + } + + log(request, "MustMatch rule failed close on URL '" + request.getRequestURL() + "'"); + return new DefaultAction(); + + } + +} diff --git a/src/main/java/org/owasp/esapi/waf/rules/PathExtensionRule.java b/src/main/java/org/owasp/esapi/waf/rules/PathExtensionRule.java new file mode 100644 index 000000000..c059ca811 --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/rules/PathExtensionRule.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) 2009 - 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 2009 + */ +package org.owasp.esapi.waf.rules; + +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.owasp.esapi.waf.actions.Action; +import org.owasp.esapi.waf.actions.DefaultAction; +import org.owasp.esapi.waf.actions.DoNothingAction; +import org.owasp.esapi.waf.internal.InterceptingHTTPServletResponse; + +/** + * This is the Rule subclass executed for <restrict-extension> rules. + * @author Arshan Dabirsiaghi + * + */ +public class PathExtensionRule extends Rule { + + private Pattern allow; + private Pattern deny; + + public PathExtensionRule (String id, Pattern allow, Pattern deny) { + this.allow = allow; + this.deny = deny; + setId(id); + } + + public Action check(HttpServletRequest request, + InterceptingHTTPServletResponse response, + HttpServletResponse httpResponse) { + + if ( allow != null && allow.matcher(request.getRequestURI()).matches() ) { + return new DoNothingAction(); + } else if ( deny != null && deny.matcher(request.getRequestURI()).matches() ) { + + log(request, "Disallowed extension pattern '" + deny.pattern() + "' found on URI '" + request.getRequestURI() + "'"); + + return new DefaultAction(); + } + + return new DoNothingAction(); + } + +} diff --git a/src/main/java/org/owasp/esapi/waf/rules/ReplaceContentRule.java b/src/main/java/org/owasp/esapi/waf/rules/ReplaceContentRule.java new file mode 100644 index 000000000..b36062bcf --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/rules/ReplaceContentRule.java @@ -0,0 +1,113 @@ +/** + * 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) 2009 - 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 2009 + */ +package org.owasp.esapi.waf.rules; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.owasp.esapi.Logger; +import org.owasp.esapi.waf.actions.Action; +import org.owasp.esapi.waf.actions.DoNothingAction; +import org.owasp.esapi.waf.configuration.AppGuardianConfiguration; +import org.owasp.esapi.waf.internal.InterceptingHTTPServletResponse; + +/** + * This is the Rule subclass executed for <dynamic-insertion> rules. + * @author Arshan Dabirsiaghi + * + */ +public class ReplaceContentRule extends Rule { + + private Pattern pattern; + private String replacement; + private Pattern contentType; + private Pattern path; + + public ReplaceContentRule(String id, Pattern pattern, String replacement, Pattern contentType, Pattern path) { + this.pattern = pattern; + this.replacement = replacement; + this.path = path; + this.contentType = contentType; + setId(id); + } + + /* + * Use regular expressions with capturing parentheses to perform replacement. + */ + + public Action check(HttpServletRequest request, + InterceptingHTTPServletResponse response, + HttpServletResponse httpResponse) { + + /* + * First early fail: if the URI doesn't match the paths we're interested in. + */ + String uri = request.getRequestURI(); + if ( path != null && ! path.matcher(uri).matches() ) { + return new DoNothingAction(); + } + + /* + * Second early fail: if the content type is one we'd like to search for output patterns. + */ + + if ( contentType != null ) { + if ( response.getContentType() != null && ! contentType.matcher(response.getContentType()).matches() ) { + return new DoNothingAction(); + } + } + + byte[] bytes = null; + + try { + bytes = response.getInterceptingServletOutputStream().getResponseBytes(); + } catch (IOException ioe) { + log(request,"Error matching pattern '" + pattern.pattern() + "', IOException encountered (possibly too large?): " + ioe.getMessage() + " (in response to URL: '" + request.getRequestURL() + "')"); + return new DoNothingAction(); // yes this is a fail open! + } + + + try { + + String s = new String(bytes,response.getCharacterEncoding()); + + Matcher m = pattern.matcher(s); + String canary = m.replaceAll(replacement); + + try { + + if ( ! s.equals(canary) ) { + response.getInterceptingServletOutputStream().setResponseBytes(canary.getBytes(response.getCharacterEncoding())); + logger.debug(Logger.SECURITY_SUCCESS, "Successfully replaced pattern '" + pattern.pattern() + "' on response to URL '" + request.getRequestURL() + "'"); + } + + } catch (IOException ioe) { + logger.error(Logger.SECURITY_FAILURE, "Failed to replace pattern '" + pattern.pattern() + "' on response to URL '" + request.getRequestURL() + "' due to [" + ioe.getMessage() + "]"); + } + + } catch(UnsupportedEncodingException uee) { + logger.error(Logger.SECURITY_FAILURE, "Failed to replace pattern '" + pattern.pattern() + "' on response to URL '" + request.getRequestURL() + "' due to [" + uee.getMessage() + "]"); + } + + return new DoNothingAction(); + } + +} diff --git a/src/main/java/org/owasp/esapi/waf/rules/RestrictContentTypeRule.java b/src/main/java/org/owasp/esapi/waf/rules/RestrictContentTypeRule.java new file mode 100644 index 000000000..43ea63aaf --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/rules/RestrictContentTypeRule.java @@ -0,0 +1,70 @@ +/** + * 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) 2009 - 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 2009 + */ +package org.owasp.esapi.waf.rules; + +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.owasp.esapi.waf.actions.Action; +import org.owasp.esapi.waf.actions.DefaultAction; +import org.owasp.esapi.waf.actions.DoNothingAction; +import org.owasp.esapi.waf.internal.InterceptingHTTPServletResponse; + +/** + * This is the Rule subclass executed for <dynamic-insertion> rules. + * @author Arshan Dabirsiaghi + * + */ +public class RestrictContentTypeRule extends Rule { + + private Pattern allow; + private Pattern deny; + + public RestrictContentTypeRule(String id, Pattern allow, Pattern deny) { + this.allow = allow; + this.deny = deny; + setId(id); + } + + public Action check(HttpServletRequest request, + InterceptingHTTPServletResponse response, + HttpServletResponse httpResponse) { + + /* can't check content type if it's not available */ + if ( request.getContentType() == null ) { + return new DoNothingAction(); + } + + if ( allow != null ) { + if ( allow.matcher(request.getContentType()).matches() ) { + return new DoNothingAction(); + } + log(request, "Disallowed content type based on allow pattern '" + allow.pattern() + "' found on URI '" + request.getRequestURI() + "' (value was '" + request.getContentType() +"')"); + } else if ( deny != null ) { + if ( ! deny.matcher(request.getContentType()).matches() ) { + return new DoNothingAction(); + } + log(request, "Disallowed content type based on deny pattern '" + deny.pattern() + "' found on URI '" + request.getRequestURI() + "' (value was '" + request.getContentType() + ")'"); + } + + + return new DefaultAction(); + + } + +} diff --git a/src/main/java/org/owasp/esapi/waf/rules/RestrictUserAgentRule.java b/src/main/java/org/owasp/esapi/waf/rules/RestrictUserAgentRule.java new file mode 100644 index 000000000..ae31b1965 --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/rules/RestrictUserAgentRule.java @@ -0,0 +1,80 @@ +/** + * 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) 2009 - 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 2009 + */ +package org.owasp.esapi.waf.rules; + +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.owasp.esapi.waf.actions.Action; +import org.owasp.esapi.waf.actions.BlockAction; +import org.owasp.esapi.waf.actions.DefaultAction; +import org.owasp.esapi.waf.actions.DoNothingAction; +import org.owasp.esapi.waf.configuration.AppGuardianConfiguration; +import org.owasp.esapi.waf.internal.InterceptingHTTPServletResponse; + +/** + * This is the Rule subclass executed for <restrict-user-agent> rules. + * @author Arshan Dabirsiaghi + * + */ +public class RestrictUserAgentRule extends Rule { + + private static final String USER_AGENT_HEADER = "User-Agent"; + + private Pattern allow; + private Pattern deny; + + public RestrictUserAgentRule(String id, Pattern allow, Pattern deny) { + this.allow = allow; + this.deny = deny; + setId(id); + } + + public Action check(HttpServletRequest request, InterceptingHTTPServletResponse response, HttpServletResponse httpResponse) { + + String userAgent = request.getHeader( USER_AGENT_HEADER ); + + if ( userAgent == null ) userAgent=""; + + if ( allow != null ) { + if ( allow.matcher(userAgent).matches() ) { + return new DoNothingAction(); + } + } else if ( deny != null ) { + if ( ! deny.matcher(userAgent).matches() ) { + return new DoNothingAction(); + } + } + + log(request, "Disallowed user agent pattern '" + deny.pattern() + "' found in user agent '" + request.getHeader(USER_AGENT_HEADER) + "'"); + + /* + * If we don't force this to "block", the user will be in an infinite loop, possibly + * eating our bandwidth, and in the case of a dread false positive, really piss them + * off. + * + * Better to just reject. + */ + if ( AppGuardianConfiguration.DEFAULT_FAIL_ACTION == AppGuardianConfiguration.REDIRECT ) { + return new BlockAction(); + } + + return new DefaultAction(); + } + +} diff --git a/src/main/java/org/owasp/esapi/waf/rules/Rule.java b/src/main/java/org/owasp/esapi/waf/rules/Rule.java new file mode 100644 index 000000000..26adc95b9 --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/rules/Rule.java @@ -0,0 +1,55 @@ +/** + * 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) 2009 - 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 2009 + */ +package org.owasp.esapi.waf.rules; + +import javax.servlet.http.HttpServletRequest; + +import javax.servlet.http.HttpServletResponse; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Logger; +import org.owasp.esapi.waf.actions.Action; +import org.owasp.esapi.waf.configuration.AppGuardianConfiguration; +import org.owasp.esapi.waf.internal.InterceptingHTTPServletResponse; + +/** + * This is the base class for the WAF rules. + * @author Arshan Dabirsiaghi + * + */ +public abstract class Rule { + + protected String id = "(no rule ID)"; + protected static Logger logger = ESAPI.getLogger(Rule.class); + + public abstract Action check( HttpServletRequest request, InterceptingHTTPServletResponse response, HttpServletResponse httpResponse ); + + public void log( HttpServletRequest request, String message ) { + logger.warning(Logger.SECURITY_FAILURE,"[IP=" + request.getRemoteAddr() + + ",Rule=" + this.getClass().getSimpleName() + ",ID="+id+"] " + message); + } + + protected void setId(String id) { + if ( id == null || "".equals(id) ) + return; + + this.id = id; + } + + public String toString() { + return "Rule:" + this.getClass().getName(); + } +} diff --git a/src/main/java/org/owasp/esapi/waf/rules/RuleUtil.java b/src/main/java/org/owasp/esapi/waf/rules/RuleUtil.java new file mode 100644 index 000000000..3b22edbe7 --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/rules/RuleUtil.java @@ -0,0 +1,151 @@ +/** + * 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) 2009 - 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 2009 + */ +package org.owasp.esapi.waf.rules; + +import java.util.Collection; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.Map; + +import org.owasp.esapi.waf.configuration.AppGuardianConfiguration; + +/** + * This is a small utility class for use by Rule subclasses. + * @author Arshan Dabirsiaghi + * + */ +public class RuleUtil { + + public static boolean isInList(Map m, String s) { + + Iterator it = m.keySet().iterator(); + + while( it.hasNext() ) { + String key = (String)it.next(); + if ( key.equals(s) ) { + return true; + } + } + + return false; + } + + public static boolean isInList(Collection c, String s) { + + Iterator it = c.iterator(); + + while(it.hasNext()) { + + Object o = it.next(); + + if ( o instanceof String ) { + + if ( s.equals((String)o)) { + return true; + } + + } else if ( o instanceof Integer ) { + + try { + if ( Integer.parseInt(s) == ((Integer)o).intValue() ) { + return true; + } + } catch (Exception e) {} + + } else if ( o instanceof Long ) { + + try { + if ( Long.parseLong(s) == ((Long)o).longValue() ) { + return true; + } + } catch (Exception e) {} + + } else if ( o instanceof Double ) { + + try { + if ( Double.compare(Double.parseDouble(s), ((Double)o).doubleValue()) == 0 ) { + return true; + } + } catch (Exception e) {} + } + + } + + return false; + } + + /* + * Enumeration + */ + public static boolean isInList(Enumeration en, String s) { + + for(; en.hasMoreElements();) { + + Object o = en.nextElement(); + + if ( o instanceof String ) { + + if ( s.equals((String)o)) { + return true; + } + + } else if ( o instanceof Integer ) { + + try { + if ( Integer.parseInt(s) == ((Integer)o).intValue() ) { + return true; + } + } catch (Exception e) {} + + } else if ( o instanceof Long ) { + + try { + if ( Long.parseLong(s) == ((Long)o).longValue() ) { + return true; + } + } catch (Exception e) {} + + } else if ( o instanceof Double ) { + + try { + if ( Double.compare(Double.parseDouble(s), ((Double)o).doubleValue()) == 0 ) { + return true; + } + } catch (Exception e) {} + } + + } + + return false; + } + + public static boolean testValue(String s, String test, int operator) { + + switch(operator) { + case AppGuardianConfiguration.OPERATOR_EQ: + + return test.equals(s); + + case AppGuardianConfiguration.OPERATOR_CONTAINS: + + return test.contains(s); + + } + + return false; + } + +} diff --git a/src/main/java/org/owasp/esapi/waf/rules/SimpleVirtualPatchRule.java b/src/main/java/org/owasp/esapi/waf/rules/SimpleVirtualPatchRule.java new file mode 100644 index 000000000..44c8e181b --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/rules/SimpleVirtualPatchRule.java @@ -0,0 +1,139 @@ +/** + * 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) 2009 - 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 2009 + */ +package org.owasp.esapi.waf.rules; + +import java.util.Enumeration; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.owasp.esapi.waf.actions.Action; +import org.owasp.esapi.waf.actions.DefaultAction; +import org.owasp.esapi.waf.actions.DoNothingAction; +import org.owasp.esapi.waf.internal.InterceptingHTTPServletRequest; +import org.owasp.esapi.waf.internal.InterceptingHTTPServletResponse; + +/** + * This is the Rule subclass executed for <virtual-patch> rules. + * @author Arshan Dabirsiaghi + * + */ +public class SimpleVirtualPatchRule extends Rule { + + private static final String REQUEST_PARAMETERS = "request.parameters."; + private static final String REQUEST_HEADERS = "request.headers."; + + private Pattern path; + private String variable; + private Pattern valid; + private String message; + + public SimpleVirtualPatchRule(String id, Pattern path, String variable, Pattern valid, String message) { + setId(id); + this.path = path; + this.variable = variable; + this.valid = valid; + this.message = message; + } + + public Action check(HttpServletRequest req, + InterceptingHTTPServletResponse response, + HttpServletResponse httpResponse) { + + InterceptingHTTPServletRequest request = (InterceptingHTTPServletRequest)req; + + String uri = request.getRequestURI(); + if ( ! path.matcher(uri).matches() ) { + + return new DoNothingAction(); + + } else { + + /* + * Decide which parameters/headers to act on. + */ + String target = null; + Enumeration en = null; + boolean parameter = true; + + if ( variable.startsWith(REQUEST_PARAMETERS)) { + + target = variable.substring(REQUEST_PARAMETERS.length()); + en = request.getParameterNames(); + + } else if ( variable.startsWith(REQUEST_HEADERS) ) { + + parameter = false; + target = variable.substring(REQUEST_HEADERS.length()); + en = request.getHeaderNames(); + + } else { + log(request, "Patch failed (improperly configured variable '" + variable + "')"); + return new DefaultAction(); + } + + /* + * If it contains a regex character, it's a regex. Loop through elements and grab any matches. + */ + if ( target.contains("*") || target.contains("?") ) { + + target = target.replaceAll("\\*", ".*"); + Pattern p = Pattern.compile(target); + while (en.hasMoreElements() ) { + String s = (String)en.nextElement(); + String value = null; + if ( p.matcher(s).matches() ) { + if ( parameter ) { + value = request.getDictionaryParameter(s); + } else { + value = request.getHeader(s); + } + if ( value != null && ! valid.matcher(value).matches() ) { + log(request, "Virtual patch tripped on variable '" + variable + "' (specifically '" + s + "'). User input was '" + value + "' and legal pattern was '" + valid.pattern() + "': " + message); + return new DefaultAction(); + } + } + } + + return new DoNothingAction(); + + } else { + + if ( parameter ) { + String value = request.getDictionaryParameter(target); + if ( value == null || valid.matcher(value).matches() ) { + return new DoNothingAction(); + } else { + log(request, "Virtual patch tripped on parameter '" + target + "'. User input was '" + value + "' and legal pattern was '" + valid.pattern() + "': " + message); + return new DefaultAction(); + } + } else { + String value = request.getHeader(target); + if ( value == null || valid.matcher(value).matches() ) { + return new DoNothingAction(); + } else { + log(request, "Virtual patch tripped on header '" + target + "'. User input was '" + value + "' and legal pattern was '" + valid.pattern() + "': " + message); + return new DefaultAction(); + } + } + } + + } + + } + +} diff --git a/src/main/java/org/owasp/esapi/waf/rules/package.html b/src/main/java/org/owasp/esapi/waf/rules/package.html new file mode 100644 index 000000000..bf418c05b --- /dev/null +++ b/src/main/java/org/owasp/esapi/waf/rules/package.html @@ -0,0 +1,12 @@ + + + + + + + +This package contains all of the Rule subclasses that correspond to policy file entries. Each +class contains the logic for enforcing its rule. + + + diff --git a/src/main/resources/ESAPI-properties.xsd b/src/main/resources/ESAPI-properties.xsd new file mode 100644 index 000000000..152411b7c --- /dev/null +++ b/src/main/resources/ESAPI-properties.xsd @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/META-INF/esapi.tld b/src/main/resources/META-INF/esapi.tld new file mode 100644 index 000000000..1a730f420 --- /dev/null +++ b/src/main/resources/META-INF/esapi.tld @@ -0,0 +1,373 @@ + + + + + + + OWASP Enterprise Security API (ESAPI) provides + a JSP Tag Library that supplies easy access to + encoding functionality in the form of JSP Tags and EL + functions. These can be used to properly escape user + supplied data at display time so that it cannot be used + in injection attacks like Cross Site Scripting (XSS). + This tag library applies to all of ESAPI 2.x versions. Its + interface hasn't changed since 2.0. + + OWASP ESAPI + 2.0 + esapi + + http://www.owasp.org/index.php/Category:OWASP_Enterprise_Security_API + + + + + Encode tag's content using Base64 + + Encode For Base64 + encodeForBase64 + + org.owasp.esapi.tags.EncodeForBase64Tag + + JSP + + + The encoding used to convert the tag + content from a String to byte[]. The + default is UTF-8. + + encoding + + + + Whether lines should be wrapped at 64 + characters. The default is false. + + wrap + boolean + + + + + + Encode tag's content for usage in CSS + + Encode For CSS + encodeForCSS + org.owasp.esapi.tags.EncodeForCSSTag + JSP + + + + + Encode tag's content for usage in HTML + + Encode For HTML + encodeForHTML + org.owasp.esapi.tags.EncodeForHTMLTag + JSP + + + + + Encode tag's content for usage in HTML Attributes + + Encode For HTML Attribute + encodeForHTMLAttribute + + org.owasp.esapi.tags.EncodeForHTMLAttributeTag + + JSP + + + + + Encode tag's content for usage in JavaScript + + Encode For JavaScript + encodeForJavaScript + + org.owasp.esapi.tags.EncodeForJavaScriptTag + + JSP + + + + + Encode tag's content for usage in URLs + + Encode For URL + encodeForURL + org.owasp.esapi.tags.EncodeForURLTag + JSP + + + + + Encode tag's content for usage in VBScript + + Encode For VBScript + encodeForVBScript + + org.owasp.esapi.tags.EncodeForVBScriptTag + + JSP + + + + + Encode tag's content for usage in XML Attributes + + Encode For XML Attribute + encodeForXMLAttribute + + org.owasp.esapi.tags.EncodeForXMLAttributeTag + + JSP + + + + + Encode tag's content for usage in XML + + Encode For XML + encodeForXML + org.owasp.esapi.tags.EncodeForXMLTag + JSP + + + + + Encode tag's content for usage in XPath + + Encode For XPath + encodeForXPath + org.owasp.esapi.tags.EncodeForXPathTag + JSP + + + + + Encodes argument in Base64. UTF-8 is used to + convert the argument from a String to byte[] + before encoding. Lines are not wrapped. + + Encode For Base64 + encodeForBase64 + + org.owasp.esapi.tags.ELEncodeFunctions + + + java.lang.String encodeForBase64(java.lang.String) + + + + + + Encodes argument in Base64. UTF-8 is used to + convert the argument from a String to byte[] + before encoding. Lines are wrapped at 64 characters. + + + Encode For Base64 with Line Wrapping + + encodeForBase64Wrap + + org.owasp.esapi.tags.ELEncodeFunctions + + + java.lang.String encodeForBase64Wrap(java.lang.String) + + + + + + Encodes the second argument in Base64. The first + argument is used as the character set used to + convert the argument from a String to byte[] + before encoding. Lines are not wrapped. + + + Encode For Base64 Using Charset + + encodeForBase64Charset + + org.owasp.esapi.tags.ELEncodeFunctions + + + java.lang.String encodeForBase64Charset( + java.lang.String, + java.lang.String) + + + + + + Encodes the second argument in Base64. The + first argument is used as the character set + used to convert the argument from a String to + byte[] before encoding. Lines are wrapped at + 64 characters. + + + Encode For Base64 Using Charset + + encodeForBase64CharsetWrap + + org.owasp.esapi.tags.ELEncodeFunctions + + + java.lang.String encodeForBase64CharsetWrap( + java.lang.String, + java.lang.String) + + + + + + Encodes the argument for use in CSS. + + Encode For Use in CSS + encodeForCSS + + org.owasp.esapi.tags.ELEncodeFunctions + + + java.lang.String encodeForCSS(java.lang.String) + + + + + + Encodes the argument for use in HTML. + + Encode For Use in HTML + encodeForHTML + + org.owasp.esapi.tags.ELEncodeFunctions + + + java.lang.String encodeForHTML(java.lang.String) + + + + + + Encodes the argument for use in HTML Attributes. + + Encode For Use in HTML Attributes + encodeForHTMLAttribute + + org.owasp.esapi.tags.ELEncodeFunctions + + + java.lang.String encodeForHTMLAttribute( + java.lang.String) + + + + + + Encodes the argument for use in JavaScript. + + Encode For Use in JavaScript + encodeForJavaScript + + org.owasp.esapi.tags.ELEncodeFunctions + + + java.lang.String encodeForJavaScript(java.lang.String) + + + + + + Encodes the argument for use in URLs. + + Encode For Use in URLs + encodeForURL + + org.owasp.esapi.tags.ELEncodeFunctions + + + java.lang.String encodeForURL(java.lang.String) + + + + + + Encodes the argument for use in VBScript. + + Encode For Use in VBScript + encodeForVBScript + + org.owasp.esapi.tags.ELEncodeFunctions + + + java.lang.String encodeForVBScript(java.lang.String) + + + + + + Encodes the argument for use in XML. + + Encode For Use in XML + encodeForXML + + org.owasp.esapi.tags.ELEncodeFunctions + + + java.lang.String encodeForXML(java.lang.String) + + + + + + Encodes the argument for use in XML Attributes. + + Encode For Use in XML Attributes + encodeForXMLAttribute + + org.owasp.esapi.tags.ELEncodeFunctions + + + java.lang.String encodeForXMLAttribute( + java.lang.String) + + + + + + Encodes the argument for use in XPath. + + Encode For Use in XPath + encodeForXPath + + org.owasp.esapi.tags.ELEncodeFunctions + + + java.lang.String encodeForXPath(java.lang.String) + + + diff --git a/src/org/owasp/esapi/AccessController.java b/src/org/owasp/esapi/AccessController.java deleted file mode 100644 index 0e26b8db9..000000000 --- a/src/org/owasp/esapi/AccessController.java +++ /dev/null @@ -1,197 +0,0 @@ -/** - * 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; - - - -/** - * 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. - * - *

- * try {
- *     ESAPI.accessController().assertAuthorizedForFunction( BUSINESS_FUNCTION );
- *     // execute BUSINESS_FUNCTION
- * } catch (AccessControlException ace) {
- * ... 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. - * - *
- * <% if ( ESAPI.accessController().isAuthorizedForFunction( ADMIN_FUNCTION ) ) { %>
- * <a href="/doAdminFunction">ADMIN</a>
- * <% } else { %>
- * <a href="/doNormalFunction">NORMAL</a>
- * <% } %>
- * 
- * - * @author Jeff Williams (jeff.williams@aspectsecurity.com) - */ -public interface AccessController { - - /** - * 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: - *
ESAPI.accessController().isAuthorizedForURL(request.getRequestURI().toString());
- * - * @param uri - * the uri as returned by request.getRequestURI().toString() - * - * @return - * true, if is authorized for URL - */ - boolean isAuthorizedForURL(String url); - - /** - * 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. - * - * @param functionName - * the function name - * - * @return - * true, if is authorized for function - */ - boolean isAuthorizedForFunction(String functionName); - - /** - * Checks if an account is authorized to access the referenced data. The implementation should define the data - * "namespace" to be enforced. - * - * @param key - * the key - * - * @return - * true, if is authorized for data - */ - boolean isAuthorizedForData(String key); - - /** - * Checks if an account is authorized to access the referenced file. The implementation should be extremely careful - * about canonicalization. - * - * @see org.owasp.esapi.Encoder#canonicalize(String) - * - * @param filepath - * the path of the file to be checked, including filename - * - * @return - * true, if is authorized for file - */ - boolean isAuthorizedForFile(String filepath); - - /** - * 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. - * - * @param serviceName - * the service name - * - * @return - * true, if is authorized for service - */ - boolean isAuthorizedForService(String serviceName); - - /** - * 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: - *
ESAPI.accessController().assertAuthorizedForURL(request.getRequestURI().toString());
- * - * @param url - * the url as returned by request.getRequestURI().toString() - * - * @throws AccessControlException - * if access is not permitted - */ - void assertAuthorizedForURL(String url) throws AccessControlException; - - /** - * 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. - * - * @param functionName - * the function name - * - * @throws AccessControlException - * if access is not permitted - */ - void assertAuthorizedForFunction(String functionName) throws AccessControlException; - - /** - * Checks if an account is authorized to access the referenced data. The implementation should define the data - * "namespace" to be enforced. - * - * @param key - * the key - * - * @throws AccessControlException - * is access is not permitted - */ - void assertAuthorizedForData(String key) throws AccessControlException; - - /** - * Checks if an account is authorized to access the referenced file. The implementation should be extremely careful - * about canonicalization. - * - * @see org.owasp.esapi.Encoder#canonicalize(String) - * - * @param filepath - * the path of the file to be checked, including filename - * - * @throws AccessControlException - * is access is not permitted - */ - void assertAuthorizedForFile(String filepath) throws AccessControlException; - - /** - * 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. - * - * @param serviceName - * the service name - * - * @throws AccessControlException - */ - void assertAuthorizedForService(String serviceName) throws AccessControlException; - - -} diff --git a/src/org/owasp/esapi/AccessReferenceMap.java b/src/org/owasp/esapi/AccessReferenceMap.java deleted file mode 100644 index f8abbb4f4..000000000 --- a/src/org/owasp/esapi/AccessReferenceMap.java +++ /dev/null @@ -1,132 +0,0 @@ -/** - * 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.Iterator; -import java.util.Set; - -import org.owasp.esapi.errors.AccessControlException; - - -/** - * 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) - */ -public interface AccessReferenceMap { - - /** - * 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 - */ - String getIndirectReference(Object 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 indirectReference is requested, then an AccessControlException is - * thrown. - * - * @param indirectReference - * the indirect reference - * - * @return the direct reference - * - * @throws AccessControlException if no direct reference exists for the - * specified indirect reference - */ - Object getDirectReference(String indirectReference) throws AccessControlException; - - /** - * Adds a direct reference to the AccessReferenceMap and generates an associated indirect reference. - * @param direct - * the direct reference - * - * @return the corresponding indirect reference - */ - String addDirectReference(Object 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 - */ - String removeDirectReference(Object direct) throws AccessControlException; - - /** - * Updates the access reference map with a new set of directReferences, maintaining - * any existing indirectReferences associated with items that are in the new list. - * @param directReferences - */ - void update(Set directReferences); - -} diff --git a/src/org/owasp/esapi/Authenticator.java b/src/org/owasp/esapi/Authenticator.java deleted file mode 100644 index 5282feaab..000000000 --- a/src/org/owasp/esapi/Authenticator.java +++ /dev/null @@ -1,279 +0,0 @@ -/** - * 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.Set; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.owasp.esapi.errors.AuthenticationException; -import org.owasp.esapi.errors.EncryptionException; - - -/** - * 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 { - - /** - * Clear the current user. This allows the thread to be reused safely. - */ - void clearCurrent(); - - /** - * Authenticates the user's credentials from the HttpServletRequest if - * necessary, creates a session if necessary, and sets the user as the - * current user. - * - * @param request - * the current HTTP request - * @param response - * the 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. 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 - * @param password - * the password - * - * @return true, if the password is correct for the specified user - */ - boolean verifyPassword(User user, String password); - - /** - * Logs out the current user. - */ - void logout(); - - /** - * 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. - * - * @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 - */ - 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. 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. - * - * @param accountId - * the account id - * - * @return the matching User object, or null if no match exists - */ - User getUser(long accountId); - - /** - * Returns the User matching the provided accountName. - * - * @param accountName - * the account name - * - * @return the matching User object, or null 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. - * - * @param password - * the password to hash - * @param accountName - * the account name to use as the salt - * - * @return the hashed password - */ - String hashPassword(String password, String accountName) throws EncryptionException; - - /** - * Removes the account. - * - * @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. 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. - * @param oldPassword - * the old password - * @param newPassword - * the new password - * - * @return 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 - */ - void verifyPasswordStrength(String oldPassword, String newPassword) 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/org/owasp/esapi/ESAPI.java b/src/org/owasp/esapi/ESAPI.java deleted file mode 100644 index dc9265e20..000000000 --- a/src/org/owasp/esapi/ESAPI.java +++ /dev/null @@ -1,282 +0,0 @@ -/** - * 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 Rogan Dawes Aspect Security - * @created 2008 - */ -package org.owasp.esapi; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.owasp.esapi.reference.DefaultEncoder; -import org.owasp.esapi.reference.DefaultExecutor; -import org.owasp.esapi.reference.DefaultHTTPUtilities; -import org.owasp.esapi.reference.DefaultIntrusionDetector; -import org.owasp.esapi.reference.DefaultRandomizer; -import org.owasp.esapi.reference.DefaultSecurityConfiguration; -import org.owasp.esapi.reference.DefaultValidator; -import org.owasp.esapi.reference.FileBasedAccessController; -import org.owasp.esapi.reference.FileBasedAuthenticator; -import org.owasp.esapi.reference.JavaEncryptor; -import org.owasp.esapi.reference.JavaLogFactory; - -/** - * 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. - */ -public class ESAPI { - - private static AccessController accessController = null; - - private static Authenticator authenticator = null; - - private static Encoder encoder = null; - - private static Encryptor encryptor = null; - - private static Executor executor = null; - - private static HTTPUtilities httpUtilities = null; - - private static IntrusionDetector intrusionDetector = null; - - private static LogFactory logFactory = null; - - private static Logger defaultLogger = null; - - private static Randomizer randomizer = null; - - private static SecurityConfiguration securityConfiguration = null; - - private static Validator validator = null; - - /** - * prevent instantiation of this class - */ - private ESAPI() { - } - - public static HttpServletRequest currentRequest() { - return httpUtilities().getCurrentRequest(); - } - - public static HttpServletResponse currentResponse() { - return httpUtilities().getCurrentResponse(); - } - - /** - * @return the accessController - */ - public static AccessController accessController() { - if (ESAPI.accessController == null) - ESAPI.accessController = new FileBasedAccessController(); - return ESAPI.accessController; - } - - /** - * @param accessController - * the accessController to set - */ - public static void setAccessController(AccessController accessController) { - ESAPI.accessController = accessController; - } - - /** - * @return the authenticator - */ - public static Authenticator authenticator() { - if (ESAPI.authenticator == null) - ESAPI.authenticator = new FileBasedAuthenticator(); - return ESAPI.authenticator; - } - - /** - * @param authenticator - * the authenticator to set - */ - public static void setAuthenticator(Authenticator authenticator) { - ESAPI.authenticator = authenticator; - } - - /** - * @return the encoder - */ - public static Encoder encoder() { - if (ESAPI.encoder == null) - ESAPI.encoder = new DefaultEncoder(); - return ESAPI.encoder; - } - - /** - * @param encoder - * the encoder to set - */ - public static void setEncoder(Encoder encoder) { - ESAPI.encoder = encoder; - } - - /** - * @return the encryptor - */ - public static Encryptor encryptor() { - if (ESAPI.encryptor == null) - ESAPI.encryptor = new JavaEncryptor(); - return ESAPI.encryptor; - } - - /** - * @param encryptor - * the encryptor to set - */ - public static void setEncryptor(Encryptor encryptor) { - ESAPI.encryptor = encryptor; - } - - /** - * @return the executor - */ - public static Executor executor() { - if (ESAPI.executor == null) - ESAPI.executor = new DefaultExecutor(); - return ESAPI.executor; - } - - /** - * @param executor - * the executor to set - */ - public static void setExecutor(Executor executor) { - ESAPI.executor = executor; - } - - /** - * @return the httpUtilities - */ - public static HTTPUtilities httpUtilities() { - if (ESAPI.httpUtilities == null) - ESAPI.httpUtilities = new DefaultHTTPUtilities(); - return ESAPI.httpUtilities; - } - - /** - * @param httpUtilities - * the httpUtilities to set - */ - public static void setHttpUtilities(HTTPUtilities httpUtilities) { - ESAPI.httpUtilities = httpUtilities; - } - - /** - * @return the intrusionDetector - */ - public static IntrusionDetector intrusionDetector() { - if (ESAPI.intrusionDetector == null) - ESAPI.intrusionDetector = new DefaultIntrusionDetector(); - return ESAPI.intrusionDetector; - } - - /** - * @param intrusionDetector - * the intrusionDetector to set - */ - public static void setIntrusionDetector(IntrusionDetector intrusionDetector) { - ESAPI.intrusionDetector = intrusionDetector; - } - - private static LogFactory logFactory() { - if (logFactory == null) - logFactory = new JavaLogFactory(securityConfiguration().getApplicationName()); - return logFactory; - } - - /** - * - */ - public static Logger getLogger(Class clazz) { - return logFactory().getLogger(clazz); - } - - /** - * - */ - public static Logger getLogger(String name) { - return logFactory().getLogger(name); - } - - public static Logger log() { - if (defaultLogger == null) - defaultLogger = logFactory().getLogger(""); - return defaultLogger; - } - - /** - * @param factory the log factory to set - */ - public static void setLogFactory(LogFactory factory) { - ESAPI.logFactory = factory; - } - - /** - * @return the randomizer - */ - public static Randomizer randomizer() { - if (ESAPI.randomizer == null) - ESAPI.randomizer = new DefaultRandomizer(); - return ESAPI.randomizer; - } - - /** - * @param randomizer - * the randomizer to set - */ - public static void setRandomizer(Randomizer randomizer) { - ESAPI.randomizer = randomizer; - } - - /** - * @return the securityConfiguration - */ - public static SecurityConfiguration securityConfiguration() { - if (ESAPI.securityConfiguration == null) - ESAPI.securityConfiguration = new DefaultSecurityConfiguration(); - return ESAPI.securityConfiguration; - } - - /** - * @param securityConfiguration - * the securityConfiguration to set - */ - public static void setSecurityConfiguration( - SecurityConfiguration securityConfiguration) { - ESAPI.securityConfiguration = securityConfiguration; - } - - /** - * @return the validator - */ - public static Validator validator() { - if (ESAPI.validator == null) - ESAPI.validator = new DefaultValidator(); - return ESAPI.validator; - } - - /** - * @param validator - * the validator to set - */ - public static void setValidator(Validator validator) { - ESAPI.validator = validator; - } - -} diff --git a/src/org/owasp/esapi/Encoder.java b/src/org/owasp/esapi/Encoder.java deleted file mode 100644 index cb223b6d9..000000000 --- a/src/org/owasp/esapi/Encoder.java +++ /dev/null @@ -1,346 +0,0 @@ -/** - * 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.IOException; - -import org.owasp.esapi.codecs.Codec; -import org.owasp.esapi.errors.EncodingException; - - -/** - * 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. - * - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security - * @since June 1, 2007 - */ -public interface Encoder { - - /** Standard character sets */ - public final static char[] CHAR_LOWERS = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' }; - public final static char[] CHAR_UPPERS = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; - public final static char[] CHAR_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; - public final static char[] CHAR_SPECIALS = { '.', '-', '_', '!', '@', '$', '^', '*', '=', '~', '|', '+', '?' }; - public final static char[] CHAR_LETTERS = StringUtilities.union(CHAR_LOWERS, CHAR_UPPERS); - public final static char[] CHAR_ALPHANUMERICS = StringUtilities.union(CHAR_LETTERS, CHAR_DIGITS); - - - /** - * 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...) - */ - public final static char[] CHAR_PASSWORD_LOWERS = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' }; - public final static char[] CHAR_PASSWORD_UPPERS = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; - public final static char[] CHAR_PASSWORD_DIGITS = { '2', '3', '4', '5', '6', '7', '8', '9' }; - public final static char[] CHAR_PASSWORD_SPECIALS = { '_', '.', '!', '@', '$', '*', '=', '-', '?' }; - public final static char[] CHAR_PASSWORD_LETTERS = StringUtilities.union( CHAR_PASSWORD_LOWERS, CHAR_PASSWORD_UPPERS ); - - - /** - * 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 semicolon. - *

- * 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. - * - * @param input the text to canonicalize - * @return a String containing the canonicalized text - * @throws EncodingException if canonicalization fails - */ - String canonicalize(String input) throws EncodingException; - - /** - * @param input - * the text to canonicalize - * @param strict - * true if checking for double encoding is desired, false otherwise - * - * @return a String containing the canonicalized text - * - * @throws EncodingException - * if canonicalization fails - */ - String canonicalize(String input, boolean strict) throws EncodingException; - - /** - * 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. - * - * @param input - * the text to normalize - * - * @return a normalized String - */ - String normalize(String input); - - /** - * Encode data for use in Cascading Style Sheets (CSS) content. - * - * @param input - * the text to encode for CSS - * - * @return input encoded for CSS - */ - String encodeForCSS(String input); - - /** - * Encode data for use in HTML content. - * - * @param input - * the text to encode for HTML - * - * @return input encoded for HTML - */ - String encodeForHTML(String input); - - /** - * Encode data for use in HTML attributes. - * - * @param input - * the text to encode for an HTML attribute - * - * @return input encoded for use as an HTML attribute - */ - String encodeForHTMLAttribute(String input); - - /** - * 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. - * - * @param input - * the text to encode for JavaScript - * - * @return input encoded for use in JavaScript - */ - String encodeForJavaScript(String input); - - /** - * 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. - * - * @param input - * the text to encode for VBScript - * - * @return input encoded for use in VBScript - */ - String encodeForVBScript(String input); - - - /** - * Encode input for use in a SQL query (this method is not recommended), according to the - * selected codec (appropriate codecs include - * the MySQLCodec and OracleCodec). - * The use of the PreparedStatement interface is - * 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. - * - * @param codec - * a 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 - */ - 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). - * - * @param codec - * a Codec that declares which database '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. - * - * @param input - * the text to encode for LDAP - * - * @return input encoded for use in LDAP - */ - String encodeForLDAP(String input); - - /** - * Encode data for use in an LDAP distinguished name. - * - * @param input - * the text to encode for an LDAP distinguished name - * - * @return input encoded for use in an LDAP distinguished name - */ - String encodeForDN(String input); - - /** - * Encode data for use in an XPath query. - * - * @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 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. - * - * @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 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. - * - * @param input - * the text to encode for use as an XML attribute - * - * @return input encoded for use in an XML attribute - */ - String encodeForXMLAttribute(String input); - - /** - * Encode for use in a URL. This method performs URL encoding" - * on the entire string. - * - * @param input - * the text to encode for use in a URL - * - * @return input encoded for use in a URL - * - * @throws EncodingException - * if encoding fails - */ - String encodeForURL(String input) throws EncodingException; - - /** - * Decode from URL. Implementations should first canonicalize and - * detect any double-encoding. If this check passes, then the data is decoded using URL - * decoding. - * - * @param input - * the text to decode from an encoded URL - * - * @return the decoded URL value - * - * @throws EncodingException - * if decoding fails - */ - String decodeFromURL(String input) throws EncodingException; - - /** - * Encode for Base64. - * - * @param input - * the text to encode for Base64 - * @param wrap - * - * @return input encoded for Base64 - */ - String encodeForBase64(byte[] input, boolean wrap); - - /** - * Decode data encoded with BASE-64 encoding. - * - * @param input - * the Base64 text to decode - * - * @return input decoded from Base64 - * - * @throws IOException - */ - byte[] decodeFromBase64(String input) throws IOException; - -} diff --git a/src/org/owasp/esapi/EncryptedProperties.java b/src/org/owasp/esapi/EncryptedProperties.java deleted file mode 100644 index f6a1c7ec2..000000000 --- a/src/org/owasp/esapi/EncryptedProperties.java +++ /dev/null @@ -1,104 +0,0 @@ -/** - * 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.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Set; - -import org.owasp.esapi.errors.EncryptionException; - - -/** - * 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. - *

- * - *

- * - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security - * @since June 1, 2007 - */ -public interface EncryptedProperties { - - /** - * Gets the property value from the encrypted store, decrypts it, and returns the plaintext value to the caller. - * - * @param key - * the key - * - * @return the decrypted property value - * - * @throws EncryptionException - * the encryption exception - */ - String getProperty(String key) throws EncryptionException; - - /** - * Encrypts the plaintext property value and stores the ciphertext value in the encrypted store. - * - * @param key - * the key - * @param value - * the value - * - * @return the encrypted property value - * - * @throws EncryptionException - * the encryption exception - */ - String setProperty(String key, String value) throws EncryptionException; - - - /** - * Key set. - * - * @return the set - */ - public Set keySet(); - - - /** - * Load. - * - * @param in - * the in - * - * @throws IOException - * Signals that an I/O exception has occurred. - */ - public void load(InputStream in) throws IOException; - - - /** - * Store. - * - * @param out - * the out - * @param comments - * the comments - * - * @throws IOException - * Signals that an I/O exception has occurred. - */ - public void store(OutputStream out, String comments) throws IOException; - - -} diff --git a/src/org/owasp/esapi/Encryptor.java b/src/org/owasp/esapi/Encryptor.java deleted file mode 100644 index 0a339683f..000000000 --- a/src/org/owasp/esapi/Encryptor.java +++ /dev/null @@ -1,182 +0,0 @@ -/** - * 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; -import org.owasp.esapi.errors.IntegrityException; - - -/** - * 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
  • - *
- * - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security - * @since June 1, 2007 - */ -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 - * - * @return the encrypted hash of 'plaintext' stored as a String - * - * @throws EncryptionException - * the encryption exception - */ - String hash(String plaintext, String salt) throws EncryptionException; - - /** - * Encrypts the provided plaintext and returns a ciphertext string. - * - * @param plaintext - * the plaintext String to encrypt - * - * @return the encrypted String - * - * @throws EncryptionException - * the encryption exception - */ - String encrypt(String plaintext) throws EncryptionException; - - /** - * Decrypts the provided ciphertext string (encrypted with the encrypt - * method) and returns a plaintext string. - * - * @param ciphertext - * the ciphertext - * - * @return the decrypted ciphertext - * - * @throws EncryptionException - * the encryption exception - */ - String decrypt(String ciphertext) throws EncryptionException; - - /** - * Create a digital signature for the provided data and return it in a - * string. - * - * @param data - * the data to sign - * - * @return the digital signature stored as a String - * - * @throws EncryptionException - * the encryption exception - */ - String sign(String data) throws EncryptionException; - - /** - * Verifies a digital signature (created with the sign method) and returns - * the boolean result. - * - * @param signature - * the signature to verify - * @param data - * the data to verify - * - * @return true, if the signature is verified - * - * @throws EncryptionException - * the encryption exception - */ - 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 EncryptionException - * the encryption exception - */ - 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 data - * - * @throws ExcryptionException 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 - * - * @return true, if the seal is valid - */ - 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 - */ - public long getRelativeTimeStamp( long offset ); - - - /** - * Gets a timestamp representing the current date and time to be used by - * other functions in the library. - * - * @return the timestamp - */ - long getTimeStamp(); - -} diff --git a/src/org/owasp/esapi/Executor.java b/src/org/owasp/esapi/Executor.java deleted file mode 100644 index 3149e678a..000000000 --- a/src/org/owasp/esapi/Executor.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * 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. - *

- * - *

- * - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security - * @since June 1, 2007 - */ -public interface Executor { - - /** - * 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 command - * 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 - * - * @return the output of the command being run - * - * @throws ExecutorException - * the service exception - */ - String executeSystemCommand(File executable, List params, File workdir, Codec codec) throws ExecutorException; - -} diff --git a/src/org/owasp/esapi/HTTPUtilities.java b/src/org/owasp/esapi/HTTPUtilities.java deleted file mode 100644 index f23eb70f8..000000000 --- a/src/org/owasp/esapi/HTTPUtilities.java +++ /dev/null @@ -1,346 +0,0 @@ -/** - * 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.io.IOException; -import java.util.List; -import java.util.Map; - -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 org.owasp.esapi.errors.AccessControlException; -import org.owasp.esapi.errors.AuthenticationException; -import org.owasp.esapi.errors.EncryptionException; -import org.owasp.esapi.errors.EnterpriseSecurityException; -import org.owasp.esapi.errors.IntrusionException; -import org.owasp.esapi.errors.ValidationException; -import org.owasp.esapi.filters.SafeRequest; -import org.owasp.esapi.filters.SafeResponse; - - -/** - * The HTTPUtilities interface is a collection of methods that provide additional security related to HTTP requests, - * responses, sessions, cookies, headers, and logging. - *

- * - *

- * - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security - * @since June 1, 2007 - */ -public interface HTTPUtilities { - - /** Key for remember token cookie */ - public final static String REMEMBER_TOKEN_COOKIE_NAME = "ESAPIRememberToken"; - - /** - * 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 {@link HTTPUtilities#getCurrentRequest()} to obtain the current {@link HttpServletRequest} object - * - * @throws AccessControlException if security constraints are not met - */ - void assertSecureRequest( HttpServletRequest request ) throws AccessControlException; - - - /** - * 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); - - /** - * Get the first cookie with the matching name. - * @param name - * @return - */ - Cookie getCookie(HttpServletRequest request, String name); - - /** - * Returns the current user's CSRF token. If there is no current user then return null. - * - * @return the current users CSRF token - */ - String getCSRFToken(); - - - /** - * 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 {@link HTTPUtilities#getCurrentRequest()} to obtain the current {@link HttpSession} object - * - * @return the new HttpSession with a changed id - * @throws EnterpriseSecurityException the enterprise security exception - */ - HttpSession changeSessionIdentifier( HttpServletRequest request ) throws AuthenticationException; - - - /** - * Checks the CSRF token in the URL (see User.getCSRFToken()) against the user's CSRF token and - * throws an IntrusionException if it is missing. - * - * @throws IntrusionException if CSRF token is missing or incorrect - */ - void verifyCSRFToken(HttpServletRequest request) throws IntrusionException; - - - /** - * 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); - - /** - * 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(); - * - * @param password - * the user's password - * @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 - */ - String setRememberToken(HttpServletRequest request,HttpServletResponse response, String password, int maxAge, String domain, String path); - - /** - * 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 (i.e. everything after the ? 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; - - /** - * 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; - - - /** - * 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 {@link HTTPUtilities#getCurrentRequest()} to obtain the {@link HttpServletRequest} object - * - * @param tempDir - * the temporary directory - * @param finalDir - * the final directory - * - * @return List of new File objects from upload - * - * @throws ValidationException - * if the file fails validation - */ - List getSafeFileUploads(HttpServletRequest request, File tempDir, File finalDir) throws ValidationException; - - /** - * Retrieves a map of data from a cookie encrypted with encryptStateInCookie(). - * - * @return a map containing the decrypted cookie state value - * - * @throws EncryptionException - */ - Map decryptStateFromCookie(HttpServletRequest request) throws EncryptionException ; - - /** - * 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. - */ - void killAllCookies(HttpServletRequest request, HttpServletResponse response); - - /** - * 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. - */ - void killCookie(HttpServletRequest request, HttpServletResponse response, String name); - - /** - * 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. - */ - void encryptStateInCookie(HttpServletResponse response, Map cleartext) throws EncryptionException; - - - /** - * 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. - * - * @param 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. - * @param location - * the URL to forward to - * - * @throws AccessControlException - * @throws ServletException - * @throws IOException - */ - void safeSendForward(HttpServletRequest request, HttpServletResponse response, String context, String location) throws AccessControlException,ServletException,IOException; - - - /** - * 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 safeSetContentType(HttpServletResponse response); - - - /** - * 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: - * - *

-     * 
-     * Cache-Control: no-store
- * Cache-Control: no-cache
- * Cache-Control: must-revalidate
- * Expires: -1
- * - *
- * - * 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: - * - * - * This method uses {@link HTTPUtilities#getCurrentResponse()} to obtain the {@link HttpServletResponse} object - * - */ - void setNoCacheHeaders(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); - - /** - * Retrieves the current HttpServletRequest - * - * @return the current request - */ - SafeRequest getCurrentRequest(); - - /** - * Retrieves the current HttpServletResponse - * - * @return the current response - */ - SafeResponse getCurrentResponse(); - - /** - * 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 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. - * - * This method uses {@link HTTPUtilities#getCurrentResponse()} to obtain the {@link HttpServletResponse} object - * - * @param logger - * the logger to write the request to - * @param parameterNamesToObfuscate - * the sensitive parameters - */ - void logHTTPRequest(HttpServletRequest request, Logger logger, List parameterNamesToObfuscate); - -} diff --git a/src/org/owasp/esapi/IntrusionDetector.java b/src/org/owasp/esapi/IntrusionDetector.java deleted file mode 100644 index f7587a4f0..000000000 --- a/src/org/owasp/esapi/IntrusionDetector.java +++ /dev/null @@ -1,60 +0,0 @@ -/** - * 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. - * - * @param exception - * the exception - * - * @throws IntrusionException the intrusion exception - */ - void addException(Exception exception) throws IntrusionException; - - /** - * Adds the event to the IntrusionDetector. - * - * @param eventName - * the event - * @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/org/owasp/esapi/LogFactory.java b/src/org/owasp/esapi/LogFactory.java deleted file mode 100644 index 926e4a6fc..000000000 --- a/src/org/owasp/esapi/LogFactory.java +++ /dev/null @@ -1,36 +0,0 @@ -/** - * 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 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. - * - * @see org.owasp.esapi.ESAPI - * - * @author rdawes - * - */ -public interface LogFactory { - - Logger getLogger(String name); - - Logger getLogger(Class clazz); - -} diff --git a/src/org/owasp/esapi/Logger.java b/src/org/owasp/esapi/Logger.java deleted file mode 100644 index 4d6208693..000000000 --- a/src/org/owasp/esapi/Logger.java +++ /dev/null @@ -1,230 +0,0 @@ -/** - * 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; - - -/** - * 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 - * - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security - * @since June 1, 2007 - */ -public interface Logger { - - String SECURITY = "SECURITY"; - String USABILITY = "USABILITY"; - String PERFORMANCE = "PERFORMANCE"; - String FUNCTIONALITY = "FUNCTIONALITY"; - - /** - * Log critical. - * - * @param type - * the type of event - * @param message - * the message to log to log - */ - void fatal(String type, String message); - - /** - * Log critical. - * - * @param type - * the type of event of event - * @param message - * the message to log to log - * @param throwable - * the exception thrown - */ - void fatal(String 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 messages will be output to the log - */ - boolean isFatalEnabled(); - - /** - * Log debug. - * - * @param type - * the type of event - * @param message - * the message to log - */ - void debug(String type, String message); - - /** - * Log debug. - * - * @param type - * the type of event - * @param message - * the message to log - * @param throwable - * the exception thrown - */ - void debug(String 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 messages will be output to the log - */ - boolean isDebugEnabled(); - - /** - * Log error. - * - * @param type - * the type of event - * @param message - * the message to log - */ - void error(String type, String message); - - /** - * Log error. - * - * @param type - * the type of event - * @param message - * the message to log - * @param throwable - * the exception thrown - */ - void error(String 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 messages will be output to the log - */ - boolean isErrorEnabled(); - - /** - * Log success. - * - * @param type - * the type of event - * @param message - * the message to log - */ - void info(String type, String message); - - /** - * Log success. - * - * @param type - * the type of event - * @param message - * the message to log - * @param throwable - * the exception thrown - */ - void info(String 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 info if messages will be output to the log - */ - boolean isInfoEnabled(); - - /** - * Log trace. - * - * @param type - * the type of event - * @param message - * the message to log - */ - void trace(String type, String message); - - /** - * Log trace. - * - * @param type - * the type of event - * @param message - * the message to log - * @param throwable - * the exception thrown - */ - void trace(String 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 messages will be output to the log - */ - boolean isTraceEnabled(); - - /** - * Log warning. - * - * @param type - * the type of event - * @param message - * the message to log - */ - void warning(String type, String message); - - /** - * Log warning. - * - * @param type - * the type of event - * @param message - * the message to log - * @param throwable - * the exception thrown - */ - void warning(String 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 messages will be output to the log - */ - boolean isWarningEnabled(); - -} diff --git a/src/org/owasp/esapi/Randomizer.java b/src/org/owasp/esapi/Randomizer.java deleted file mode 100644 index b0e89c913..000000000 --- a/src/org/owasp/esapi/Randomizer.java +++ /dev/null @@ -1,107 +0,0 @@ -/** - * 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 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. - *

- * - *

- * @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. - * - * @param length - * the length of the string - * @param characterSet - * the character set - * - * @return the random string - */ - String getRandomString(int length, char[] characterSet); - - /** - * Returns a random boolean. - * - * @return true or false, randomly - */ - boolean getRandomBoolean(); - - /** - * Gets the random integer. - * - * @param min - * the minimum integer that will be returned - * @param max - * the maximum integer that will be returned - * - * @return the random integer - */ - int getRandomInteger(int min, int max); - - - /** - * Gets the random long. - * - * @return the random long - */ - public long getRandomLong(); - - - /** - * Returns an unguessable random filename with the specified extension. - * @param extenstion - * extension to add to the random filename - * - * @return a random unguessable filename ending with the specified extension - */ - public String getRandomFilename( String extension ); - - - /** - * Gets the random real. - * - * @param min - * the minimum real number that will be returned - * @param max - * the maximum real number that will be returned - * - * @return the random real - */ - float getRandomReal(float min, float max); - - /** - * Generates a random GUID. - * - * @return the GUID - * - * @throws EncryptionException - */ - String getRandomGUID() throws EncryptionException; - -} diff --git a/src/org/owasp/esapi/SafeFile.java b/src/org/owasp/esapi/SafeFile.java deleted file mode 100644 index 071ab2e83..000000000 --- a/src/org/owasp/esapi/SafeFile.java +++ /dev/null @@ -1,107 +0,0 @@ -/** - * 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; - - 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()); - } - - - Pattern percents = Pattern.compile("(%)([0-9a-fA-F])([0-9a-fA-F])"); - Pattern dirblacklist = Pattern.compile("([*?<>|])"); - private void doDirCheck(String path) throws ValidationException { - Matcher m1 = dirblacklist.matcher( path ); - if ( m1.find() ) { - throw new ValidationException( "Invalid directory", "Directory path (" + path + ") contains illegal character: " + m1.group() ); - } - - Matcher m2 = percents.matcher( path ); - if ( 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); - } - } - - Pattern fileblacklist = Pattern.compile("([\\\\/:*?<>|])"); - private void doFileCheck(String path) throws ValidationException { - Matcher m1 = fileblacklist.matcher( path ); - if ( m1.find() ) { - throw new ValidationException( "Invalid directory", "Directory path (" + path + ") contains illegal character: " + m1.group() ); - } - - Matcher m2 = percents.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/org/owasp/esapi/SecurityConfiguration.java b/src/org/owasp/esapi/SecurityConfiguration.java deleted file mode 100644 index 48152d0cc..000000000 --- a/src/org/owasp/esapi/SecurityConfiguration.java +++ /dev/null @@ -1,204 +0,0 @@ -/** - * 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; - - -/** - * 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. - * - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security - * @since June 1, 2007 - */ -public interface SecurityConfiguration { - - /** - * Gets the application name, used for logging - * - * @return the application name - */ - public String getApplicationName(); - - /** - * Gets the master password. - * - * @return the master password - */ - public char[] getMasterPassword(); - - /** - * Gets the keystore. - * - * @return the keystore - */ - public File getKeystore(); - - /** - * Gets the master salt. - * - * @return the master salt - */ - public byte[] getMasterSalt(); - - /** - * Gets the allowed file extensions. - * - * @return the allowed file extensions - */ - public List getAllowedFileExtensions(); - - /** - * Gets the allowed file upload size. - * - * @return the allowed file upload size - */ - public int getAllowedFileUploadSize(); - - /** - * Gets the password parameter name. - * - * @return the password parameter name - */ - public String getPasswordParameterName(); - - /** - * Gets the username parameter name. - * - * @return the username parameter name - */ - public String getUsernameParameterName(); - - /** - * Gets the encryption algorithm. - * - * @return the encryption algorithm - */ - public String getEncryptionAlgorithm(); - - /** - * Gets the hashing algorithm. - * - * @return the hashing algorithm - */ - public String getHashAlgorithm(); - - /** - * Gets the character encoding. - * - * @return encoding character name - */ - public String getCharacterEncoding(); - - /** - * Gets the digital signature algorithm. - * - * @return the digital signature algorithm - */ - public String getDigitalSignatureAlgorithm(); - - /** - * Gets the random number generation algorithm. - * - * @return random number generation algorithm - */ - public String getRandomAlgorithm(); - - /** - * Gets the allowed login attempts. - * - * @return the allowed login attempts - */ - public int getAllowedLoginAttempts(); - - /** - * Gets the max old password hashes. - * - * @return the max old password hashes - */ - public int getMaxOldPasswordHashes(); - - /** - * Gets an intrusion detection Quota. - * - * @param eventName - * the event whose quota is desired - * - * @return the matching Quota for eventName - */ - public Threshold getQuota(String eventName); - - /** - * Gets the ESAPI resource directory as a String. - * - * @return the ESAPI resource directory - */ - public String getResourceDirectory(); - - /** - * Sets the ESAPI resource directory. - * - * @param dir - * location of the resource directory - */ - public void setResourceDirectory(String dir); - - /** - * Gets the content-type set for responses. - */ - public String getResponseContentType(); - - /** - * Gets the time window allowed for the remember token in milliseconds. - */ - public long getRememberTokenDuration(); - - /** - * Returns whether HTML entity encoding should be applied to log entries. - */ - public boolean getLogEncodingRequired(); - - - /** - * Models a simple threshold as a count and an interval, along with a set of actions to take if the threshold is exceeded. - */ - public static class Threshold { - public String name = null; - public int count = 0; - public long interval = 0; - public List actions = null; - - public Threshold(String name, int count, long interval, List actions) { - this.name = name; - this.count = count; - this.interval = interval; - this.actions = actions; - } - } -} \ No newline at end of file diff --git a/src/org/owasp/esapi/StringUtilities.java b/src/org/owasp/esapi/StringUtilities.java deleted file mode 100644 index db54271c4..000000000 --- a/src/org/owasp/esapi/StringUtilities.java +++ /dev/null @@ -1,84 +0,0 @@ -/** - * 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; - -/** - * String utilities used in various filters. - * - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security - * @since June 1, 2007 - */ -public class StringUtilities { - - /** - * Removes all unprintable characters from a string - * and replaces with a space for use in an HTTP header - * @param input - * @return the stripped header - */ - public static String stripControls( String input ) { - StringBuffer sb = new StringBuffer(); - for ( int i=0; i 0x20 && c < 0x7f ) { - sb.append( c ); - } else { - sb.append( ' ' ); - } - } - return sb.toString(); - } - - - /** - * Union two character arrays. - * - * @param c1 the c1 - * @param c2 the c2 - * @return the char[] - */ - public static char[] union(char[] c1, char[] c2) { - StringBuffer sb = new StringBuffer(); - for (int i = 0; i < c1.length; i++) { - if (!contains(sb, c1[i])) - sb.append(c1[i]); - } - for (int i = 0; i < c2.length; i++) { - if (!contains(sb, c2[i])) - sb.append(c2[i]); - } - char[] c3 = new char[sb.length()]; - sb.getChars(0, sb.length(), c3, 0); - Arrays.sort(c3); - return c3; - } - - - /** - * Returns true if the character is contained in the provided StringBuffer. - */ - public static boolean contains(StringBuffer haystack, char c) { - for (int i = 0; i < haystack.length(); i++) { - if (haystack.charAt(i) == c) - return true; - } - return false; - } - -} \ No newline at end of file diff --git a/src/org/owasp/esapi/User.java b/src/org/owasp/esapi/User.java deleted file mode 100644 index 14729db83..000000000 --- a/src/org/owasp/esapi/User.java +++ /dev/null @@ -1,655 +0,0 @@ -/** - * 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.security.Principal; -import java.util.Date; -import java.util.HashSet; -import java.util.Set; - -import org.owasp.esapi.errors.AuthenticationException; -import org.owasp.esapi.errors.EncryptionException; -import org.owasp.esapi.reference.DefaultEncoder; - -/** - * 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 - * @since June 1, 2007 - */ - -public interface User extends Principal { - - /** - * Adds a role to an account. - * - * @param role - * the role to add - * - * @throws AuthenticationException - * the authentication exception - */ - void addRole(String role) throws AuthenticationException; - - /** - * Adds a set of roles to an 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 account. - * - * @throws AuthenticationException the authentication exception - */ - void disable(); - - /** - * Enable account. - * - * @throws AuthenticationException the authentication exception - */ - void enable(); - - /** - * Gets the account id. - * - * @return the account id - */ - long getAccountId(); - - /** - * Gets the account name. - * - * @return the account name - */ - String getAccountName(); - - /** - * Gets the CSRF token. - * - * @return the CSRF token - */ - String getCSRFToken(); - - /** - * Returns the date that the current user's account will expire, usually when the account will be disabled. - * - * @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. - * - * @return the screen name - */ - String getScreenName(); - - /** - * Increment failed login count. - */ - void incrementFailedLoginCount(); - - /** - * Checks if user is anonymous. - * - * @return true, if user is anonymous - */ - boolean isAnonymous(); - - /** - * Checks if an account is currently enabled. - * - * @return true, if account is enabled - */ - boolean isEnabled(); - - /** - * Checks if an account is expired. - * - * @return true, if account is expired - */ - boolean isExpired(); - - /** - * Checks if an account has been 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 an 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 the user's session has exceeded the absolute time out. - * - * @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. - * - * @return true, if user's session has timed out from inactivity - */ - boolean isSessionTimeout(); - - /** - * Lock the 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 an 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 the account name. - * - * @param accountName the new account name - */ - void setAccountName(String accountName); - - /** - * Sets the time when this user's account will expire. - * - * @param expirationTime the new expiration time - */ - void setExpirationTime(Date expirationTime); - - /** - * Sets the roles of this account. - * - * @param roles - * the new roles - * - * @throws AuthenticationException - * the authentication exception - */ - void setRoles(Set roles) throws AuthenticationException; - - /** - * Sets the screen name. - * - * @param screenName the new screen name - */ - void setScreenName(String screenName); - - /** - * Unlock 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 - */ - public boolean verifyPassword(String password) throws EncryptionException; - - /** - * Set the time of the last failed login for this user. - * @param lastFailedLoginTime - */ - void setLastFailedLoginTime(Date lastFailedLoginTime); - - /** - * Set the last remote host address used by this user. - * @param remoteHost - */ - void setLastHostAddress(String remoteHost); - - /** - * Set the time of the last successful login for this user. - * @param lastLoginTime - */ - void setLastLoginTime(Date lastLoginTime); - - /** - * Set the time of the last password change for this user. - * @param lastPasswordChangeTime - */ - void setLastPasswordChangeTime(Date lastPasswordChangeTime); - - - - /** - * 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. - */ - public final User ANONYMOUS = new User() { - - private String csrfToken = ""; - - /* (non-Javadoc) - * @see org.owasp.esapi.User#addRole(java.lang.String) - */ - public void addRole(String role) throws AuthenticationException { - throw new RuntimeException("Invalid operation for the anonymous user"); - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#addRoles(java.util.Set) - */ - public void addRoles(Set newRoles) throws AuthenticationException { - throw new RuntimeException("Invalid operation for the anonymous user"); - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#changePassword(java.lang.String, java.lang.String, java.lang.String) - */ - public void changePassword(String oldPassword, String newPassword1, - String newPassword2) throws AuthenticationException, - EncryptionException { - throw new RuntimeException("Invalid operation for the anonymous user"); - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#disable() - */ - public void disable() { - throw new RuntimeException("Invalid operation for the anonymous user"); - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#enable() - */ - public void enable() { - throw new RuntimeException("Invalid operation for the anonymous user"); - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#getAccountId() - */ - public long getAccountId() { - return 0; - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#getAccountName() - */ - public String getAccountName() { - return "Anonymous"; - } - - public String getName() { - return getAccountName(); - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#getCSRFToken() - */ - public String getCSRFToken() { - return csrfToken; - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#getLastFailedLoginTime() - */ - public Date getExpirationTime() { - return null; - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#getFailedLoginCount() - */ - public int getFailedLoginCount() { - return 0; - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#getLastFailedLoginTime() - */ - public Date getLastFailedLoginTime() throws AuthenticationException { - return null; - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#getLastHostAddress() - */ - public String getLastHostAddress() { - return "unknown"; - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#getLastLoginTime() - */ - public Date getLastLoginTime() { - return null; - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#getLastPasswordChangeTime() - */ - public Date getLastPasswordChangeTime() { - return null; - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#getRoles() - */ - public Set getRoles() { - return new HashSet(); - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#getScreenName() - */ - public String getScreenName() { - return "Anonymous"; - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#incrementFailedLoginCount() - */ - public void incrementFailedLoginCount() { - throw new RuntimeException("Invalid operation for the anonymous user"); - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#isAnonymous() - */ - public boolean isAnonymous() { - return true; - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#isEnabled() - */ - public boolean isEnabled() { - return false; - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#isExpired() - */ - public boolean isExpired() { - return false; - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#isInRole(java.lang.String) - */ - public boolean isInRole(String role) { - return false; - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#isLocked() - */ - public boolean isLocked() { - return false; - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#isLoggedIn() - */ - public boolean isLoggedIn() { - return false; - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#isSessionAbsoluteTimeout() - */ - public boolean isSessionAbsoluteTimeout() { - return false; - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#isSessionTimeout() - */ - public boolean isSessionTimeout() { - return false; - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#lock() - */ - public void lock() { - throw new RuntimeException("Invalid operation for the anonymous user"); - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#loginWithPassword(java.lang.String) - */ - public void loginWithPassword(String password) - throws AuthenticationException { - throw new RuntimeException("Invalid operation for the anonymous user"); - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#logout() - */ - public void logout() { - throw new RuntimeException("Invalid operation for the anonymous user"); - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#removeRole(java.lang.String) - */ - public void removeRole(String role) throws AuthenticationException { - throw new RuntimeException("Invalid operation for the anonymous user"); - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#resetCSRFToken() - */ - public String resetCSRFToken() throws AuthenticationException { - csrfToken = ESAPI.randomizer().getRandomString(8, DefaultEncoder.CHAR_ALPHANUMERICS); - return csrfToken; - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#setAccountName(java.lang.String) - */ - public void setAccountName(String accountName) { - throw new RuntimeException("Invalid operation for the anonymous user"); - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#setAccountName(java.lang.String) - */ - public void setExpirationTime(Date expirationTime) { - throw new RuntimeException("Invalid operation for the anonymous user"); - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#setRoles(java.util.Set) - */ - public void setRoles(Set roles) throws AuthenticationException { - throw new RuntimeException("Invalid operation for the anonymous user"); - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#setScreenName(java.lang.String) - */ - public void setScreenName(String screenName) { - throw new RuntimeException("Invalid operation for the anonymous user"); - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#unlock() - */ - public void unlock() { - throw new RuntimeException("Invalid operation for the anonymous user"); - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#verifyPassword(java.lang.String) - */ - public boolean verifyPassword(String password) throws EncryptionException { - throw new RuntimeException("Invalid operation for the anonymous user"); - } - - public void setLastFailedLoginTime(Date lastFailedLoginTime) { - throw new RuntimeException("Invalid operation for the anonymous user"); - } - - public void setLastLoginTime(Date lastLoginTime) { - throw new RuntimeException("Invalid operation for the anonymous user"); - } - - public void setLastHostAddress(String remoteHost) { - throw new RuntimeException("Invalid operation for the anonymous user"); - } - - public void setLastPasswordChangeTime(Date lastPasswordChangeTime) { - throw new RuntimeException("Invalid operation for the anonymous user"); - } - }; -} diff --git a/src/org/owasp/esapi/ValidationErrorList.java b/src/org/owasp/esapi/ValidationErrorList.java deleted file mode 100644 index 280fdef43..000000000 --- a/src/org/owasp/esapi/ValidationErrorList.java +++ /dev/null @@ -1,143 +0,0 @@ -/** - * 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.ArrayList; -import java.util.HashMap; -import java.util.List; - -import org.owasp.esapi.errors.ValidationException; - -/** - * 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: - * - *

- * ValidationErrorList() errorList = new ValidationErrorList();.
- * String name  = getValidInput("Name", form.getName(), "SomeESAPIRegExName1", 255, false, errorList);
- * String address = getValidInput("Address", form.getAddress(), "SomeESAPIRegExName2", 255, false, errorList);
- * Integer weight = getValidInteger("Weight", form.getWeight(), 1, 1000000000, false, errorList);
- * Integer sortOrder = getValidInteger("Sort Order", form.getSortOrder(), -100000, +100000, false, errorList);
- * request.setAttribute( "ERROR_LIST", errorList );
- * 
- * - * The at your view layer you would be able to retrieve all - * of your error messages via a helper function like: - * - *
- * public static ValidationErrorList getErrors() {          
- *     HttpServletRequest request = ESAPI.httpUtilities().getCurrentRequest();
- *     ValidationErrorList errors = new ValidationErrorList();
- *     if (request.getAttribute(Constants.ERROR_LIST) != null) {
- *        errors = (ValidationErrorList)request.getAttribute("ERROR_LIST");
- *     }
- * 	   return errors;
- * }
- * 
- * - * You can list all errors like: - * - *
- * <%
- *      for (Object vo : errorList.errors()) {
- *         ValidationException ve = (ValidationException)vo;
- * %>
- * <%= ESAPI.encoder().encodeForHTML(ve.getMessage()) %>
- * <% - * } - * %> - *
- * - * And even check if a specific UI component is in error via calls like: - * - *
- * ValidationException e = errorList.getError("Name");
- * 
- * - * @author Jim Manico (jim.manico .at. aspectsecurity.com) - * Aspect Security - * @since August 15, 2008 - */ -public class ValidationErrorList { - - /** - * Error list of ValidationException's - */ - private HashMap errorList = new HashMap(); - - /** - * Adds a new error to list with a unique named context. - * No action taken if either element is null. - * Existing contexts will be overwritten. - * - * @param context unique named context for this ValidationErrorList - * @param ve - */ - public void addError(String context, ValidationException ve) { - if (getError(context) != null) throw new RuntimeException("Context (" + context + ") already exists, programmer error"); - - if ((context != null) && (ve != null)) { - errorList.put(context, ve); - } - } - - /** - * Returns list of ValidationException, or empty list of no errors exist. - * - * @return List - */ - public List errors() { - return new ArrayList( errorList.values() ); - } - - /** - * Retrieves ValidationException for given context if one exists. - * - * @param context unique name for each error - * @return ValidationException or null for given context - */ - public ValidationException getError(String context) { - if (context == null) return null; - return (ValidationException)errorList.get(context); - } - - /** - * Returns true if no error are present. - * - * @return boolean - */ - public boolean isEmpty() { - return errorList.isEmpty(); - } - - /** - * Returns the numbers of errors present. - * - * @return boolean - */ - public int size() { - return errorList.size(); - } -} diff --git a/src/org/owasp/esapi/Validator.java b/src/org/owasp/esapi/Validator.java deleted file mode 100644 index 514034a09..000000000 --- a/src/org/owasp/esapi/Validator.java +++ /dev/null @@ -1,1066 +0,0 @@ -/** - * 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.InputStream; -import java.text.DateFormat; -import java.util.Date; -import java.util.List; -import java.util.Set; - -import org.owasp.esapi.errors.IntrusionException; -import org.owasp.esapi.errors.ValidationException; - - -/** - * 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. - * - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security - * @since June 1, 2007 - */ -public interface Validator { - - /** - * 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. - * - * @param 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. - * @param input - * The actual user input data to validate. - * @param type - * The regular expression name that maps to the actual regular expression from "ESAPI.properties". - * @param maxLength - * The maximum post-canonicalized String length allowed. - * @param 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. - * - * @return true, if the input is valid based on the rules set by 'type' - * - * @throws IntrusionException - */ - boolean isValidInput(String context, String input, String type, int maxLength, boolean allowNull) throws IntrusionException; - - /** - * 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. - * - * @param 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. - * @param input - * The actual user input data to validate. - * @param type - * The regular expression name that maps to the actual regular expression from "ESAPI.properties". - * @param maxLength - * The maximum post-canonicalized String length allowed. - * @param 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. - * - * @return The canonicalized user input. - * - * @throws ValidationException - * @throws IntrusionException - */ - String getValidInput(String context, String input, String type, int maxLength, boolean allowNull) throws ValidationException, IntrusionException; - - /** - * 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. - * - * @param 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. - * @param input - * The actual user input data to validate. - * @param type - * The regular expression name that maps to the actual regular expression from "ESAPI.properties". - * @param maxLength - * The maximum post-canonicalized String length allowed. - * @param 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. - * @param errorList - * If validation is in error, resulting error will be stored in the errorList by context - * - * @return The canonicalized user input. - * - * @throws IntrusionException - */ - String getValidInput(String context, String input, String type, int maxLength, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; - - /** - * Returns true if input is a valid date according to the specified date format. - * - * @param 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. - * @param input - * The actual user input data to validate. - * @param format - * Required formatting of date inputted. - * @param 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. - * - * @return true, if input is a valid date according to the format specified by 'format' - * - * @throws IntrusionException - */ - boolean isValidDate(String context, String input, DateFormat format, boolean allowNull) throws IntrusionException; - - /** - * 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. - * - * @param 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. - * @param input - * The actual user input data to validate. - * @param format - * Required formatting of date inputted. - * @param 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. - * - * @return A valid date as a Date - * - * @throws ValidationException - * @throws IntrusionException - */ - Date getValidDate(String context, String input, DateFormat format, boolean allowNull) throws ValidationException, IntrusionException; - - /** - * 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. - * - * @param 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. - * @param input - * The actual user input data to validate. - * @param format - * Required formatting of date inputted. - * @param 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. - * @param errorList - * If validation is in error, resulting error will be stored in the errorList by context - * - * @return A valid date as a Date - * - * @throws IntrusionException - */ - Date getValidDate(String context, String input, DateFormat format, boolean allowNull, ValidationErrorList errorList) throws 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. - * - * @param 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. - * @param input - * The actual user input data to validate. - * @param maxLength - * The maximum post-canonicalized String length allowed. - * @param 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. - * - * @return true, if input is valid safe HTML - * - * @throws IntrusionException - */ - boolean isValidSafeHTML(String context, String input, int maxLength, boolean allowNull) throws IntrusionException; - - /** - * 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. - * - * @param 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. - * @param input - * The actual user input data to validate. - * @param maxLength - * The maximum post-canonicalized String length allowed. - * @param 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. - * - * @return Valid safe HTML - * - * @throws ValidationException - * @throws IntrusionException - */ - String getValidSafeHTML(String context, String input, int maxLength, boolean allowNull) throws ValidationException, IntrusionException; - - /** - * 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. - * - * @param 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. - * @param input - * The actual user input data to validate. - * @param maxLength - * The maximum post-canonicalized String length allowed. - * @param 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. - * @param errorList - * If validation is in error, resulting error will be stored in the errorList by context - * - * @return Valid safe HTML - * - * @throws IntrusionException - */ - String getValidSafeHTML(String context, String input, int maxLength, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; - - /** - * Returns true if input is a valid credit card. Maxlength is mandated by valid credit card type. - * - * @param 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. - * @param input - * The actual user input data to validate. - * @param 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. - * - * @return true, if input is a valid credit card number - * - * @throws IntrusionException - */ - boolean isValidCreditCard(String context, String input, boolean allowNull) throws IntrusionException; - - /** - * 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. - * - * @param 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. - * @param input - * The actual user input data to validate. - * @param 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. - * - * @return A valid credit card number - * - * @throws ValidationException - * @throws IntrusionException - */ - String getValidCreditCard(String context, String input, boolean allowNull) throws ValidationException, IntrusionException; - - /** - * 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. - * - * @param 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. - * @param input - * The actual input data to validate. - * @param 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. - * @param errorList - * If validation is in error, resulting error will be stored in the errorList by context - * - * @return A valid credit card number - * - * @throws IntrusionException - */ - String getValidCreditCard(String context, String input, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; - - /** - * Returns true if input is a valid directory path. - * - * @param 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. - * @param input - * The actual input data to validate. - * @param 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. - * - * @return true, if input is a valid directory path - * - * @throws IntrusionException - */ - boolean isValidDirectoryPath(String context, String input, boolean allowNull) throws 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. - * - * @param 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. - * @param input - * The actual input data to validate. - * @param 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. - * - * @return A valid directory path - * - * @throws ValidationException - * @throws IntrusionException - */ - String getValidDirectoryPath(String context, String input, boolean allowNull) throws ValidationException, 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. Instead of throwing a ValidationException - * on error, this variant will store the exception inside of the ValidationErrorList. - * - * @param 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. - * @param input - * The actual input data to validate. - * @param 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. - * @param errorList - * If validation is in error, resulting error will be stored in the errorList by context - * - * @return A valid directory path - * - * @throws IntrusionException - */ - String getValidDirectoryPath(String context, String input, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; - - - /** - * Returns true if input is a valid file name. - * - * @param 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. - * @param input - * The actual input data to validate. - * @param 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. - * - * @return true, if input is a valid file name - * - * @throws IntrusionException - */ - boolean isValidFileName(String context, String input, boolean allowNull) throws IntrusionException; - - /** - * 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. - * - * @param 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. - * @param input - * The actual input data to validate. - * @param 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. - * - * @return A valid file name - * - * @throws ValidationException - * @throws IntrusionException - */ - String getValidFileName(String context, String input, boolean allowNull) throws ValidationException, IntrusionException; - - /** - * 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. - * - * @param 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. - * @param input - * The actual input data to validate. - * @param 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. - * @param errorList - * If validation is in error, resulting error will be stored in the errorList by context - * - * @return A valid file name - * - * @throws IntrusionException - */ - String getValidFileName(String context, String input, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; - - /** - * Returns true if input is a valid number within the range of minValue to maxValue. - * - * @param 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. - * @param input - * The actual input data to validate. - * @param minValue - * Lowest legal value for input. - * @param maxValue - * Highest legal value for input. - * @param 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. - * - * @return true, if input is a valid number - * - * @throws IntrusionException - */ - boolean isValidNumber(String context, String input, long minValue, long maxValue, boolean allowNull) throws IntrusionException; - - /** - * 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. - * - * @param 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. - * @param input - * The actual input data to validate. - * @param 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. - * @param minValue - * Lowest legal value for input. - * @param maxValue - * Highest legal value for input. - * - * @return A validated number as a double. - * - * @throws ValidationException - * @throws IntrusionException - */ - Double getValidNumber(String context, String input, long minValue, long maxValue, boolean allowNull) throws ValidationException, IntrusionException; - - /** - * 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. - * - * @param 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. - * @param input - * The actual input data to validate. - * @param minValue - * Lowest legal value for input. - * @param maxValue - * Highest legal value for input. - * @param 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. - * @param errorList - * If validation is in error, resulting error will be stored in the errorList by context - * - * @return A validated number as a double. - * - * @throws IntrusionException - */ - Double getValidNumber(String context, String input, long minValue, long maxValue, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; - - /** - * Returns true if input is a valid integer within the range of minValue to maxValue. - * - * @param 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. - * @param input - * The actual input data to validate. - * @param minValue - * Lowest legal value for input. - * @param maxValue - * Highest legal value for input. - * @param 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. - * - * @return true, if input is a valid integer - * - * @throws IntrusionException - */ - boolean isValidInteger(String context, String input, int minValue, int maxValue, boolean allowNull) throws IntrusionException; - - /** - * Returns a validated integer. Invalid input - * will generate a descriptive ValidationException, and input that is clearly an attack - * will generate a descriptive IntrusionException. - * - * @param 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. - * @param input - * The actual input data to validate. - * @param 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. - * @param minValue - * Lowest legal value for input. - * @param maxValue - * Highest legal value for input. - * - * @return A validated number as an integer. - * - * @throws ValidationException - * @throws IntrusionException - */ - Integer getValidInteger(String context, String input, int minValue, int maxValue, boolean allowNull) throws ValidationException, IntrusionException; - - /** - * 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. - * - * @param 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. - * @param input - * The actual input data to validate. - * @param minValue - * Lowest legal value for input. - * @param maxValue - * Highest legal value for input. - * @param 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. - * @param errorList - * If validation is in error, resulting error will be stored in the errorList by context - * - * @return A validated number as an integer. - * - * @throws IntrusionException - */ - Integer getValidInteger(String context, String input, int minValue, int maxValue, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; - - /** - * Returns true if input is a valid double within the range of minValue to maxValue. - * - * @param 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. - * @param input - * The actual input data to validate. - * @param minValue - * Lowest legal value for input. - * @param maxValue - * Highest legal value for input. - * @param 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. - * - * @return true, if input is a valid double. - * - * @throws IntrusionException - * - */ - boolean isValidDouble(String context, String input, double minValue, double maxValue, boolean allowNull) throws 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. - * - * @param 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. - * @param input - * The actual input data to validate. - * @param 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. - * @param minValue - * Lowest legal value for input. - * @param maxValue - * Highest legal value for input. - * - * @return A validated real number as a double. - * - * @throws ValidationException - * @throws IntrusionException - */ - Double getValidDouble(String context, String input, double minValue, double maxValue, boolean allowNull) throws ValidationException, 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. Instead of throwing a ValidationException - * on error, this variant will store the exception inside of the ValidationErrorList. - * - * @param 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. - * @param input - * The actual input data to validate. - * @param minValue - * Lowest legal value for input. - * @param maxValue - * Highest legal value for input. - * @param 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. - * @param errorList - * If validation is in error, resulting error will be stored in the errorList by context - * - * @return A validated real number as a double. - * - * @throws IntrusionException - */ - Double getValidDouble(String context, String input, double minValue, double maxValue, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; - - /** - * 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. - * - * @param 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. - * @param input - * The actual input data to validate. - * @param maxBytes - * The maximum number of bytes allowed in a legal file. - * @param 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. - * - * @return true, if input contains valid file content. - * - * @throws IntrusionException - */ - boolean isValidFileContent(String context, byte[] input, int maxBytes, boolean allowNull) throws IntrusionException; - - /** - * 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. - * - * @param 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. - * @param input - * The actual input data to validate. - * @param maxBytes - * The maximum number of bytes allowed in a legal file. - * @param 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. - * - * @return A byte array containing valid file content. - * - * @throws ValidationException - * @throws IntrusionException - */ - byte[] getValidFileContent(String context, byte[] input, int maxBytes, boolean allowNull) throws ValidationException, IntrusionException; - - /** - * 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. - * - * @param 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. - * @param input - * The actual input data to validate. - * @param maxBytes - * The maximum number of bytes allowed in a legal file. - * @param 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. - * @param errorList - * If validation is in error, resulting error will be stored in the errorList by context. - * - * @return A byte array containing valid file content. - * - * @throws IntrusionException - */ - byte[] getValidFileContent(String context, byte[] input, int maxBytes, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; - - /** - * Returns true if a file upload has a valid name, path, and content. - * - * @param 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. - * @param filepath - * The file path of the uploaded file. - * @param filename - * The filename of the uploaded file - * @param content - * A byte array containing the content of the uploaded file. - * @param maxBytes - * The max number of bytes allowed for a legal file upload. - * @param 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. - * - * @return true, if a file upload has a valid name, path, and content. - * - * @throws IntrusionException - */ - boolean isValidFileUpload(String context, String filepath, String filename, byte[] content, int maxBytes, boolean allowNull) throws 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. - * - * @param 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. - * @param filepath - * The file path of the uploaded file. - * @param filename - * The filename of the uploaded file - * @param content - * A byte array containing the content of the uploaded file. - * @param maxBytes - * The max number of bytes allowed for a legal file upload. - * @param 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. - * - * @throws ValidationException - * @throws IntrusionException - */ - void assertValidFileUpload(String context, String filepath, String filename, byte[] content, int maxBytes, boolean allowNull) throws ValidationException, 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. Instead of throwing a ValidationException - * on error, this variant will store the exception inside of the ValidationErrorList. - * - * @param 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. - * @param filepath - * The file path of the uploaded file. - * @param filename - * The filename of the uploaded file - * @param content - * A byte array containing the content of the uploaded file. - * @param maxBytes - * The max number of bytes allowed for a legal file upload. - * @param 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. - * @param errorList - * If validation is in error, resulting error will be stored in the errorList by context - * - * @throws IntrusionException - */ - void assertValidFileUpload(String context, String filepath, String filename, byte[] content, int maxBytes, boolean allowNull, ValidationErrorList errorList) throws 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. - * - * @return true, if is a valid HTTP request - * - * @throws IntrusionException - */ - boolean isValidHTTPRequest() throws 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. - * - * @throws ValidationException - * @throws IntrusionException - */ - void assertIsValidHTTPRequest() throws ValidationException, IntrusionException; - - /** - * Returns true if input is a valid list item. - * - * @param 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. - * @param input - * The value to search 'list' for. - * @param list - * The list to search for 'input'. - * - * @return true, if 'input' was found in 'list'. - * - * @throws IntrusionException - */ - boolean isValidListItem(String context, String input, List list) throws 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. - * - * @param 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. - * @param input - * The value to search 'list' for. - * @param list - * The list to search for 'input'. - * - * @return The list item that exactly matches the canonicalized input. - * - * @throws ValidationException - * @throws IntrusionException - */ - String getValidListItem(String context, String input, List list) throws ValidationException, 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. Instead of throwing a ValidationException - * on error, this variant will store the exception inside of the ValidationErrorList. - * - * @param 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. - * @param input - * The value to search 'list' for. - * @param list - * The list to search for 'input'. - * @param errorList - * If validation is in error, resulting error will be stored in the errorList by context - * - * @return The list item that exactly matches the canonicalized input. - * - * @throws IntrusionException - */ - String getValidListItem(String context, String input, List list, ValidationErrorList errorList) throws IntrusionException; - - /** - * Returns true if the parameters in the current request contain all required parameters and only optional ones in addition. - * - * @param 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. - * @param required - * parameters that are required to be in HTTP request - * @param optional - * additional parameters that may be in HTTP request - * - * @return 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. - * - * @throws IntrusionException - */ - boolean isValidHTTPRequestParameterSet(String context, Set required, Set optional) throws 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. - * - * @param 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. - * @param required - * parameters that are required to be in HTTP request - * @param optional - * additional parameters that may be in HTTP request - * - * @throws ValidationException - * @throws IntrusionException - */ - void assertIsValidHTTPRequestParameterSet(String context, Set required, Set optional) throws ValidationException, 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. Instead of throwing a ValidationException on error, - * this variant will store the exception inside of the ValidationErrorList. - * - * @param 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. - * @param required - * parameters that are required to be in HTTP request - * @param optional - * additional parameters that may be in HTTP request - * @param errorList - * If validation is in error, resulting error will be stored in the errorList by context - * - * @throws IntrusionException - */ - void assertIsValidHTTPRequestParameterSet(String context, Set required, Set optional, ValidationErrorList errorList) throws IntrusionException; - - /** - * Returns true if input contains only valid printable ASCII characters. - * - * @param 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. - * @param input - * data to be checked for validity - * @param maxLength - * Maximum number of bytes stored in 'input' - * @param 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. - * - * @return true, if 'input' is less than maxLength and contains only valid, printable characters - * - * @throws IntrusionException - */ - boolean isValidPrintable(String context, byte[] input, int maxLength, boolean allowNull) throws 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. - * - * @param 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. - * @param input - * data to be returned as valid and printable - * @param maxLength - * Maximum number of bytes stored in 'input' - * @param 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. - * - * @return a byte array containing only printable characters, made up of data from 'input' - * - * @throws ValidationException - */ - byte[] getValidPrintable(String context, byte[] input, int maxLength, boolean allowNull) throws ValidationException; - - /** - * 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. - * - * @param 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. - * @param input - * data to be returned as valid and printable - * @param maxLength - * Maximum number of bytes stored in 'input' - * @param 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. - * @param errorList - * If validation is in error, resulting error will be stored in the errorList by context - * - * @return a byte array containing only printable characters, made up of data from 'input' - * - * @throws IntrusionException - */ - byte[] getValidPrintable(String context, byte[] input, int maxLength, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; - - - /** - * Returns true if input contains only valid printable ASCII characters (32-126). - * - * @param 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. - * @param input - * data to be checked for validity - * @param maxLength - * Maximum number of bytes stored in 'input' after canonicalization - * @param 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. - * - * @return true, if 'input' is less than maxLength after canonicalization and contains only valid, printable characters - * - * @throws IntrusionException - */ - boolean isValidPrintable(String context, String input, int maxLength, boolean allowNull) throws 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. - * - * @param 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. - * @param input - * data to be returned as valid and printable - * @param maxLength - * Maximum number of bytes stored in 'input' after canonicalization - * @param 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. - * - * @return a String containing only printable characters, made up of data from 'input' - * - * @throws ValidationException - */ - String getValidPrintable(String context, String input, int maxLength, boolean allowNull) throws ValidationException; - - /** - * 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. - * - * @param 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. - * @param input - * data to be returned as valid and printable - * @param maxLength - * Maximum number of bytes stored in 'input' after canonicalization - * @param 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. - * @param errorList - * If validation is in error, resulting error will be stored in the errorList by context - * - * @return a String containing only printable characters, made up of data from 'input' - * - * @throws IntrusionException - */ - String getValidPrintable(String context, String input, int maxLength, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; - - /** - * Returns true if input is a valid redirect location, as defined by "ESAPI.properties". - * - * @param 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. - * @param input - * redirect location to be checked for validity, according to rules set in "ESAPI.properties" - * @param 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. - * - * @return true, if 'input' is a valid redirect location, as defined by "ESAPI.properties", false otherwise. - * - * @throws IntrusionException - */ - boolean isValidRedirectLocation(String context, String input, boolean allowNull) throws 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. - * - * @param 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. - * @param input - * redirect location to be returned as valid, according to encoding rules set in "ESAPI.properties" - * @param 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. - * - * @return A canonicalized and validated redirect location, as defined in "ESAPI.properties" - * - * @throws ValidationException - * @throws IntrusionException - */ - String getValidRedirectLocation(String context, String input, boolean allowNull) throws ValidationException, 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. Instead of throwing a ValidationException - * on error, this variant will store the exception inside of the ValidationErrorList. - * - * @param 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. - * @param input - * redirect location to be returned as valid, according to encoding rules set in "ESAPI.properties" - * @param 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. - * @param errorList - * If validation is in error, resulting error will be stored in the errorList by context - * - * @return A canonicalized and validated redirect location, as defined in "ESAPI.properties" - * - * @throws IntrusionException - */ - String getValidRedirectLocation(String context, String input, boolean allowNull, ValidationErrorList errorList) throws IntrusionException; - - /** - * 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. - * - * @param inputStream - * The InputStream from which to read data - * @param maxLength - * Maximum characters allowed to be read in per line - * - * @return a String containing the current line of inputStream - * - * @throws ValidationException - */ - String safeReadLine(InputStream inputStream, int maxLength) throws ValidationException; - -} - diff --git a/src/org/owasp/esapi/codecs/CSSCodec.java b/src/org/owasp/esapi/codecs/CSSCodec.java deleted file mode 100644 index 93dacb8a9..000000000 --- a/src/org/owasp/esapi/codecs/CSSCodec.java +++ /dev/null @@ -1,131 +0,0 @@ -/** - * 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.codecs; - - -/** - * Implementation of the Codec interface for backslash encoding frequently used in JavaScript. - * - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security - * @since June 1, 2007 - * @see org.owasp.esapi.Encoder - */ -public class CSSCodec implements Codec { - - public CSSCodec() { - } - - public String encode( String input ) { - StringBuffer sb = new StringBuffer(); - for ( int i=0; ihttp://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.codecs; - - -/** - * 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. - * - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security - * @since June 1, 2007 - * @see org.owasp.esapi.Encoder - */ -public interface Codec { - - - String encode( String input ); - - String encodeCharacter( Character c ); - - String decode( String input ); - - - /** - * 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. - */ - public Character decodeCharacter( PushbackString input ); - -} \ No newline at end of file diff --git a/src/org/owasp/esapi/codecs/HTMLEntityCodec.java b/src/org/owasp/esapi/codecs/HTMLEntityCodec.java deleted file mode 100644 index 3097ae590..000000000 --- a/src/org/owasp/esapi/codecs/HTMLEntityCodec.java +++ /dev/null @@ -1,751 +0,0 @@ -/** - * 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.codecs; - -import java.util.HashMap; - -/** - * Implementation of the Codec interface for HTML entity encoding. - * - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security - * @since June 1, 2007 - * @see org.owasp.esapi.Encoder - */ -public class HTMLEntityCodec implements Codec { - - private static HashMap characterToEntityMap; - - private static HashMap entityToCharacterMap; - - public HTMLEntityCodec() { - initializeMaps(); - } - - public String encode( String input ) { - StringBuffer sb = new StringBuffer(); - for ( int i=0; i> " + possible ); - Character entity = (Character) entityToCharacterMap.get(possible.toString()); - if ( entity != null ) { - // eat any trailing semicolons - if ( input.peek( ';') ) { - input.next(); - } - return entity; - } - } - return null; - } - - - public static void main( String[] args ) { - HTMLEntityCodec codec = new HTMLEntityCodec(); - String test = "<"; - // String test = "% <script> <script> <script> <script> <script> <script>"; - System.out.println( "Original: " + test ); - System.out.println( "Decoded: " + codec.decode( test ) ); - } - - - private void initializeMaps() { - String[] entityNames = { "quot" - /* 34 : quotation mark */, "amp" - /* 38 : ampersand */, "lt" - /* 60 : less-than sign */, "gt" - /* 62 : greater-than sign */, "nbsp" - /* 160 : no-break space */, "iexcl" - /* 161 : inverted exclamation mark */, "cent" - /* 162 : cent sign */, "pound" - /* 163 : pound sign */, "curren" - /* 164 : currency sign */, "yen" - /* 165 : yen sign */, "brvbar" - /* 166 : broken bar */, "sect" - /* 167 : section sign */, "uml" - /* 168 : diaeresis */, "copy" - /* 169 : copyright sign */, "ordf" - /* 170 : feminine ordinal indicator */, "laquo" - /* 171 : left-pointing double angle quotation mark */, "not" - /* 172 : not sign */, "shy" - /* 173 : soft hyphen */, "reg" - /* 174 : registered sign */, "macr" - /* 175 : macron */, "deg" - /* 176 : degree sign */, "plusmn" - /* 177 : plus-minus sign */, "sup2" - /* 178 : superscript two */, "sup3" - /* 179 : superscript three */, "acute" - /* 180 : acute accent */, "micro" - /* 181 : micro sign */, "para" - /* 182 : pilcrow sign */, "middot" - /* 183 : middle dot */, "cedil" - /* 184 : cedilla */, "sup1" - /* 185 : superscript one */, "ordm" - /* 186 : masculine ordinal indicator */, "raquo" - /* 187 : right-pointing double angle quotation mark */, "frac14" - /* 188 : vulgar fraction one quarter */, "frac12" - /* 189 : vulgar fraction one half */, "frac34" - /* 190 : vulgar fraction three quarters */, "iquest" - /* 191 : inverted question mark */, "Agrave" - /* 192 : Latin capital letter a with grave */, "Aacute" - /* 193 : Latin capital letter a with acute */, "Acirc" - /* 194 : Latin capital letter a with circumflex */, "Atilde" - /* 195 : Latin capital letter a with tilde */, "Auml" - /* 196 : Latin capital letter a with diaeresis */, "Aring" - /* 197 : Latin capital letter a with ring above */, "AElig" - /* 198 : Latin capital letter ae */, "Ccedil" - /* 199 : Latin capital letter c with cedilla */, "Egrave" - /* 200 : Latin capital letter e with grave */, "Eacute" - /* 201 : Latin capital letter e with acute */, "Ecirc" - /* 202 : Latin capital letter e with circumflex */, "Euml" - /* 203 : Latin capital letter e with diaeresis */, "Igrave" - /* 204 : Latin capital letter i with grave */, "Iacute" - /* 205 : Latin capital letter i with acute */, "Icirc" - /* 206 : Latin capital letter i with circumflex */, "Iuml" - /* 207 : Latin capital letter i with diaeresis */, "ETH" - /* 208 : Latin capital letter eth */, "Ntilde" - /* 209 : Latin capital letter n with tilde */, "Ograve" - /* 210 : Latin capital letter o with grave */, "Oacute" - /* 211 : Latin capital letter o with acute */, "Ocirc" - /* 212 : Latin capital letter o with circumflex */, "Otilde" - /* 213 : Latin capital letter o with tilde */, "Ouml" - /* 214 : Latin capital letter o with diaeresis */, "times" - /* 215 : multiplication sign */, "Oslash" - /* 216 : Latin capital letter o with stroke */, "Ugrave" - /* 217 : Latin capital letter u with grave */, "Uacute" - /* 218 : Latin capital letter u with acute */, "Ucirc" - /* 219 : Latin capital letter u with circumflex */, "Uuml" - /* 220 : Latin capital letter u with diaeresis */, "Yacute" - /* 221 : Latin capital letter y with acute */, "THORN" - /* 222 : Latin capital letter thorn */, "szlig" - /* 223 : Latin small letter sharp s, German Eszett */, "agrave" - /* 224 : Latin small letter a with grave */, "aacute" - /* 225 : Latin small letter a with acute */, "acirc" - /* 226 : Latin small letter a with circumflex */, "atilde" - /* 227 : Latin small letter a with tilde */, "auml" - /* 228 : Latin small letter a with diaeresis */, "aring" - /* 229 : Latin small letter a with ring above */, "aelig" - /* 230 : Latin lowercase ligature ae */, "ccedil" - /* 231 : Latin small letter c with cedilla */, "egrave" - /* 232 : Latin small letter e with grave */, "eacute" - /* 233 : Latin small letter e with acute */, "ecirc" - /* 234 : Latin small letter e with circumflex */, "euml" - /* 235 : Latin small letter e with diaeresis */, "igrave" - /* 236 : Latin small letter i with grave */, "iacute" - /* 237 : Latin small letter i with acute */, "icirc" - /* 238 : Latin small letter i with circumflex */, "iuml" - /* 239 : Latin small letter i with diaeresis */, "eth" - /* 240 : Latin small letter eth */, "ntilde" - /* 241 : Latin small letter n with tilde */, "ograve" - /* 242 : Latin small letter o with grave */, "oacute" - /* 243 : Latin small letter o with acute */, "ocirc" - /* 244 : Latin small letter o with circumflex */, "otilde" - /* 245 : Latin small letter o with tilde */, "ouml" - /* 246 : Latin small letter o with diaeresis */, "divide" - /* 247 : division sign */, "oslash" - /* 248 : Latin small letter o with stroke */, "ugrave" - /* 249 : Latin small letter u with grave */, "uacute" - /* 250 : Latin small letter u with acute */, "ucirc" - /* 251 : Latin small letter u with circumflex */, "uuml" - /* 252 : Latin small letter u with diaeresis */, "yacute" - /* 253 : Latin small letter y with acute */, "thorn" - /* 254 : Latin small letter thorn */, "yuml" - /* 255 : Latin small letter y with diaeresis */, "OElig" - /* 338 : Latin capital ligature oe */, "oelig" - /* 339 : Latin small ligature oe */, "Scaron" - /* 352 : Latin capital letter s with caron */, "scaron" - /* 353 : Latin small letter s with caron */, "Yuml" - /* 376 : Latin capital letter y with diaeresis */, "fnof" - /* 402 : Latin small letter f with hook */, "circ" - /* 710 : modifier letter circumflex accent */, "tilde" - /* 732 : small tilde */, "Alpha" - /* 913 : Greek capital letter alpha */, "Beta" - /* 914 : Greek capital letter beta */, "Gamma" - /* 915 : Greek capital letter gamma */, "Delta" - /* 916 : Greek capital letter delta */, "Epsilon" - /* 917 : Greek capital letter epsilon */, "Zeta" - /* 918 : Greek capital letter zeta */, "Eta" - /* 919 : Greek capital letter eta */, "Theta" - /* 920 : Greek capital letter theta */, "Iota" - /* 921 : Greek capital letter iota */, "Kappa" - /* 922 : Greek capital letter kappa */, "Lambda" - /* 923 : Greek capital letter lambda */, "Mu" - /* 924 : Greek capital letter mu */, "Nu" - /* 925 : Greek capital letter nu */, "Xi" - /* 926 : Greek capital letter xi */, "Omicron" - /* 927 : Greek capital letter omicron */, "Pi" - /* 928 : Greek capital letter pi */, "Rho" - /* 929 : Greek capital letter rho */, "Sigma" - /* 931 : Greek capital letter sigma */, "Tau" - /* 932 : Greek capital letter tau */, "Upsilon" - /* 933 : Greek capital letter upsilon */, "Phi" - /* 934 : Greek capital letter phi */, "Chi" - /* 935 : Greek capital letter chi */, "Psi" - /* 936 : Greek capital letter psi */, "Omega" - /* 937 : Greek capital letter omega */, "alpha" - /* 945 : Greek small letter alpha */, "beta" - /* 946 : Greek small letter beta */, "gamma" - /* 947 : Greek small letter gamma */, "delta" - /* 948 : Greek small letter delta */, "epsilon" - /* 949 : Greek small letter epsilon */, "zeta" - /* 950 : Greek small letter zeta */, "eta" - /* 951 : Greek small letter eta */, "theta" - /* 952 : Greek small letter theta */, "iota" - /* 953 : Greek small letter iota */, "kappa" - /* 954 : Greek small letter kappa */, "lambda" - /* 955 : Greek small letter lambda */, "mu" - /* 956 : Greek small letter mu */, "nu" - /* 957 : Greek small letter nu */, "xi" - /* 958 : Greek small letter xi */, "omicron" - /* 959 : Greek small letter omicron */, "pi" - /* 960 : Greek small letter pi */, "rho" - /* 961 : Greek small letter rho */, "sigmaf" - /* 962 : Greek small letter final sigma */, "sigma" - /* 963 : Greek small letter sigma */, "tau" - /* 964 : Greek small letter tau */, "upsilon" - /* 965 : Greek small letter upsilon */, "phi" - /* 966 : Greek small letter phi */, "chi" - /* 967 : Greek small letter chi */, "psi" - /* 968 : Greek small letter psi */, "omega" - /* 969 : Greek small letter omega */, "thetasym" - /* 977 : Greek theta symbol */, "upsih" - /* 978 : Greek upsilon with hook symbol */, "piv" - /* 982 : Greek pi symbol */, "ensp" - /* 8194 : en space */, "emsp" - /* 8195 : em space */, "thinsp" - /* 8201 : thin space */, "zwnj" - /* 8204 : zero width non-joiner */, "zwj" - /* 8205 : zero width joiner */, "lrm" - /* 8206 : left-to-right mark */, "rlm" - /* 8207 : right-to-left mark */, "ndash" - /* 8211 : en dash */, "mdash" - /* 8212 : em dash */, "lsquo" - /* 8216 : left single quotation mark */, "rsquo" - /* 8217 : right single quotation mark */, "sbquo" - /* 8218 : single low-9 quotation mark */, "ldquo" - /* 8220 : left double quotation mark */, "rdquo" - /* 8221 : right double quotation mark */, "bdquo" - /* 8222 : double low-9 quotation mark */, "dagger" - /* 8224 : dagger */, "Dagger" - /* 8225 : double dagger */, "bull" - /* 8226 : bullet */, "hellip" - /* 8230 : horizontal ellipsis */, "permil" - /* 8240 : per mille sign */, "prime" - /* 8242 : prime */, "Prime" - /* 8243 : double prime */, "lsaquo" - /* 8249 : single left-pointing angle quotation mark */, "rsaquo" - /* 8250 : single right-pointing angle quotation mark */, "oline" - /* 8254 : overline */, "frasl" - /* 8260 : fraction slash */, "euro" - /* 8364 : euro sign */, "image" - /* 8465 : black-letter capital i */, "weierp" - /* 8472 : script capital p, Weierstrass p */, "real" - /* 8476 : black-letter capital r */, "trade" - /* 8482 : trademark sign */, "alefsym" - /* 8501 : alef symbol */, "larr" - /* 8592 : leftwards arrow */, "uarr" - /* 8593 : upwards arrow */, "rarr" - /* 8594 : rightwards arrow */, "darr" - /* 8595 : downwards arrow */, "harr" - /* 8596 : left right arrow */, "crarr" - /* 8629 : downwards arrow with corner leftwards */, "lArr" - /* 8656 : leftwards double arrow */, "uArr" - /* 8657 : upwards double arrow */, "rArr" - /* 8658 : rightwards double arrow */, "dArr" - /* 8659 : downwards double arrow */, "hArr" - /* 8660 : left right double arrow */, "forall" - /* 8704 : for all */, "part" - /* 8706 : partial differential */, "exist" - /* 8707 : there exists */, "empty" - /* 8709 : empty set */, "nabla" - /* 8711 : nabla */, "isin" - /* 8712 : element of */, "notin" - /* 8713 : not an element of */, "ni" - /* 8715 : contains as member */, "prod" - /* 8719 : n-ary product */, "sum" - /* 8721 : n-ary summation */, "minus" - /* 8722 : minus sign */, "lowast" - /* 8727 : asterisk operator */, "radic" - /* 8730 : square root */, "prop" - /* 8733 : proportional to */, "infin" - /* 8734 : infinity */, "ang" - /* 8736 : angle */, "and" - /* 8743 : logical and */, "or" - /* 8744 : logical or */, "cap" - /* 8745 : intersection */, "cup" - /* 8746 : union */, "int" - /* 8747 : integral */, "there4" - /* 8756 : therefore */, "sim" - /* 8764 : tilde operator */, "cong" - /* 8773 : congruent to */, "asymp" - /* 8776 : almost equal to */, "ne" - /* 8800 : not equal to */, "equiv" - /* 8801 : identical to, equivalent to */, "le" - /* 8804 : less-than or equal to */, "ge" - /* 8805 : greater-than or equal to */, "sub" - /* 8834 : subset of */, "sup" - /* 8835 : superset of */, "nsub" - /* 8836 : not a subset of */, "sube" - /* 8838 : subset of or equal to */, "supe" - /* 8839 : superset of or equal to */, "oplus" - /* 8853 : circled plus */, "otimes" - /* 8855 : circled times */, "perp" - /* 8869 : up tack */, "sdot" - /* 8901 : dot operator */, "lceil" - /* 8968 : left ceiling */, "rceil" - /* 8969 : right ceiling */, "lfloor" - /* 8970 : left floor */, "rfloor" - /* 8971 : right floor */, "lang" - /* 9001 : left-pointing angle bracket */, "rang" - /* 9002 : right-pointing angle bracket */, "loz" - /* 9674 : lozenge */, "spades" - /* 9824 : black spade suit */, "clubs" - /* 9827 : black club suit */, "hearts" - /* 9829 : black heart suit */, "diams" - /* 9830 : black diamond suit */, }; - - char[] entityValues = { 34 - /* " : quotation mark */, 38 - /* & : ampersand */, 60 - /* < : less-than sign */, 62 - /* > : greater-than sign */, 160 - /*   : no-break space */, 161 - /* ¡ : inverted exclamation mark */, 162 - /* ¢ : cent sign */, 163 - /* £ : pound sign */, 164 - /* ¤ : currency sign */, 165 - /* ¥ : yen sign */, 166 - /* ¦ : broken bar */, 167 - /* § : section sign */, 168 - /* ¨ : diaeresis */, 169 - /* © : copyright sign */, 170 - /* ª : feminine ordinal indicator */, 171 - /* « : left-pointing double angle quotation mark */, 172 - /* ¬ : not sign */, 173 - /* ­ : soft hyphen */, 174 - /* ® : registered sign */, 175 - /* ¯ : macron */, 176 - /* ° : degree sign */, 177 - /* ± : plus-minus sign */, 178 - /* ² : superscript two */, 179 - /* ³ : superscript three */, 180 - /* ´ : acute accent */, 181 - /* µ : micro sign */, 182 - /* ¶ : pilcrow sign */, 183 - /* · : middle dot */, 184 - /* ¸ : cedilla */, 185 - /* ¹ : superscript one */, 186 - /* º : masculine ordinal indicator */, 187 - /* » : right-pointing double angle quotation mark */, 188 - /* ¼ : vulgar fraction one quarter */, 189 - /* ½ : vulgar fraction one half */, 190 - /* ¾ : vulgar fraction three quarters */, 191 - /* ¿ : inverted question mark */, 192 - /* À : Latin capital letter a with grave */, 193 - /* Á : Latin capital letter a with acute */, 194 - /*  : Latin capital letter a with circumflex */, 195 - /* à : Latin capital letter a with tilde */, 196 - /* Ä : Latin capital letter a with diaeresis */, 197 - /* Å : Latin capital letter a with ring above */, 198 - /* Æ : Latin capital letter ae */, 199 - /* Ç : Latin capital letter c with cedilla */, 200 - /* È : Latin capital letter e with grave */, 201 - /* É : Latin capital letter e with acute */, 202 - /* Ê : Latin capital letter e with circumflex */, 203 - /* Ë : Latin capital letter e with diaeresis */, 204 - /* Ì : Latin capital letter i with grave */, 205 - /* Í : Latin capital letter i with acute */, 206 - /* Î : Latin capital letter i with circumflex */, 207 - /* Ï : Latin capital letter i with diaeresis */, 208 - /* Ð : Latin capital letter eth */, 209 - /* Ñ : Latin capital letter n with tilde */, 210 - /* Ò : Latin capital letter o with grave */, 211 - /* Ó : Latin capital letter o with acute */, 212 - /* Ô : Latin capital letter o with circumflex */, 213 - /* Õ : Latin capital letter o with tilde */, 214 - /* Ö : Latin capital letter o with diaeresis */, 215 - /* × : multiplication sign */, 216 - /* Ø : Latin capital letter o with stroke */, 217 - /* Ù : Latin capital letter u with grave */, 218 - /* Ú : Latin capital letter u with acute */, 219 - /* Û : Latin capital letter u with circumflex */, 220 - /* Ü : Latin capital letter u with diaeresis */, 221 - /* Ý : Latin capital letter y with acute */, 222 - /* Þ : Latin capital letter thorn */, 223 - /* ß : Latin small letter sharp s, German Eszett */, 224 - /* à : Latin small letter a with grave */, 225 - /* á : Latin small letter a with acute */, 226 - /* â : Latin small letter a with circumflex */, 227 - /* ã : Latin small letter a with tilde */, 228 - /* ä : Latin small letter a with diaeresis */, 229 - /* å : Latin small letter a with ring above */, 230 - /* æ : Latin lowercase ligature ae */, 231 - /* ç : Latin small letter c with cedilla */, 232 - /* è : Latin small letter e with grave */, 233 - /* é : Latin small letter e with acute */, 234 - /* ê : Latin small letter e with circumflex */, 235 - /* ë : Latin small letter e with diaeresis */, 236 - /* ì : Latin small letter i with grave */, 237 - /* í : Latin small letter i with acute */, 238 - /* î : Latin small letter i with circumflex */, 239 - /* ï : Latin small letter i with diaeresis */, 240 - /* ð : Latin small letter eth */, 241 - /* ñ : Latin small letter n with tilde */, 242 - /* ò : Latin small letter o with grave */, 243 - /* ó : Latin small letter o with acute */, 244 - /* ô : Latin small letter o with circumflex */, 245 - /* õ : Latin small letter o with tilde */, 246 - /* ö : Latin small letter o with diaeresis */, 247 - /* ÷ : division sign */, 248 - /* ø : Latin small letter o with stroke */, 249 - /* ù : Latin small letter u with grave */, 250 - /* ú : Latin small letter u with acute */, 251 - /* û : Latin small letter u with circumflex */, 252 - /* ü : Latin small letter u with diaeresis */, 253 - /* ý : Latin small letter y with acute */, 254 - /* þ : Latin small letter thorn */, 255 - /* ÿ : Latin small letter y with diaeresis */, 338 - /* Œ : Latin capital ligature oe */, 339 - /* œ : Latin small ligature oe */, 352 - /* Š : Latin capital letter s with caron */, 353 - /* š : Latin small letter s with caron */, 376 - /* Ÿ : Latin capital letter y with diaeresis */, 402 - /* ƒ : Latin small letter f with hook */, 710 - /* ˆ : modifier letter circumflex accent */, 732 - /* ˜ : small tilde */, 913 - /* Α : Greek capital letter alpha */, 914 - /* Β : Greek capital letter beta */, 915 - /* Γ : Greek capital letter gamma */, 916 - /* Δ : Greek capital letter delta */, 917 - /* Ε : Greek capital letter epsilon */, 918 - /* Ζ : Greek capital letter zeta */, 919 - /* Η : Greek capital letter eta */, 920 - /* Θ : Greek capital letter theta */, 921 - /* Ι : Greek capital letter iota */, 922 - /* Κ : Greek capital letter kappa */, 923 - /* Λ : Greek capital letter lambda */, 924 - /* Μ : Greek capital letter mu */, 925 - /* Ν : Greek capital letter nu */, 926 - /* Ξ : Greek capital letter xi */, 927 - /* Ο : Greek capital letter omicron */, 928 - /* Π : Greek capital letter pi */, 929 - /* Ρ : Greek capital letter rho */, 931 - /* Σ : Greek capital letter sigma */, 932 - /* Τ : Greek capital letter tau */, 933 - /* Υ : Greek capital letter upsilon */, 934 - /* Φ : Greek capital letter phi */, 935 - /* Χ : Greek capital letter chi */, 936 - /* Ψ : Greek capital letter psi */, 937 - /* Ω : Greek capital letter omega */, 945 - /* α : Greek small letter alpha */, 946 - /* β : Greek small letter beta */, 947 - /* γ : Greek small letter gamma */, 948 - /* δ : Greek small letter delta */, 949 - /* ε : Greek small letter epsilon */, 950 - /* ζ : Greek small letter zeta */, 951 - /* η : Greek small letter eta */, 952 - /* θ : Greek small letter theta */, 953 - /* ι : Greek small letter iota */, 954 - /* κ : Greek small letter kappa */, 955 - /* λ : Greek small letter lambda */, 956 - /* μ : Greek small letter mu */, 957 - /* ν : Greek small letter nu */, 958 - /* ξ : Greek small letter xi */, 959 - /* ο : Greek small letter omicron */, 960 - /* π : Greek small letter pi */, 961 - /* ρ : Greek small letter rho */, 962 - /* ς : Greek small letter final sigma */, 963 - /* σ : Greek small letter sigma */, 964 - /* τ : Greek small letter tau */, 965 - /* υ : Greek small letter upsilon */, 966 - /* φ : Greek small letter phi */, 967 - /* χ : Greek small letter chi */, 968 - /* ψ : Greek small letter psi */, 969 - /* ω : Greek small letter omega */, 977 - /* ϑ : Greek theta symbol */, 978 - /* ϒ : Greek upsilon with hook symbol */, 982 - /* ϖ : Greek pi symbol */, 8194 - /*   : en space */, 8195 - /*   : em space */, 8201 - /*   : thin space */, 8204 - /* ‌ : zero width non-joiner */, 8205 - /* ‍ : zero width joiner */, 8206 - /* ‎ : left-to-right mark */, 8207 - /* ‏ : right-to-left mark */, 8211 - /* – : en dash */, 8212 - /* — : em dash */, 8216 - /* ‘ : left single quotation mark */, 8217 - /* ’ : right single quotation mark */, 8218 - /* ‚ : single low-9 quotation mark */, 8220 - /* “ : left double quotation mark */, 8221 - /* ” : right double quotation mark */, 8222 - /* „ : double low-9 quotation mark */, 8224 - /* † : dagger */, 8225 - /* ‡ : double dagger */, 8226 - /* • : bullet */, 8230 - /* … : horizontal ellipsis */, 8240 - /* ‰ : per mille sign */, 8242 - /* ′ : prime */, 8243 - /* ″ : double prime */, 8249 - /* ‹ : single left-pointing angle quotation mark */, 8250 - /* › : single right-pointing angle quotation mark */, 8254 - /* ‾ : overline */, 8260 - /* ⁄ : fraction slash */, 8364 - /* € : euro sign */, 8465 - /* ℑ : black-letter capital i */, 8472 - /* ℘ : script capital p, Weierstrass p */, 8476 - /* ℜ : black-letter capital r */, 8482 - /* ™ : trademark sign */, 8501 - /* ℵ : alef symbol */, 8592 - /* ← : leftwards arrow */, 8593 - /* ↑ : upwards arrow */, 8594 - /* → : rightwards arrow */, 8595 - /* ↓ : downwards arrow */, 8596 - /* ↔ : left right arrow */, 8629 - /* ↵ : downwards arrow with corner leftwards */, 8656 - /* ⇐ : leftwards double arrow */, 8657 - /* ⇑ : upwards double arrow */, 8658 - /* ⇒ : rightwards double arrow */, 8659 - /* ⇓ : downwards double arrow */, 8660 - /* ⇔ : left right double arrow */, 8704 - /* ∀ : for all */, 8706 - /* ∂ : partial differential */, 8707 - /* ∃ : there exists */, 8709 - /* ∅ : empty set */, 8711 - /* ∇ : nabla */, 8712 - /* ∈ : element of */, 8713 - /* ∉ : not an element of */, 8715 - /* ∋ : contains as member */, 8719 - /* ∏ : n-ary product */, 8721 - /* ∑ : n-ary summation */, 8722 - /* − : minus sign */, 8727 - /* ∗ : asterisk operator */, 8730 - /* √ : square root */, 8733 - /* ∝ : proportional to */, 8734 - /* ∞ : infinity */, 8736 - /* ∠ : angle */, 8743 - /* ∧ : logical and */, 8744 - /* ∨ : logical or */, 8745 - /* ∩ : intersection */, 8746 - /* ∪ : union */, 8747 - /* ∫ : integral */, 8756 - /* ∴ : therefore */, 8764 - /* ∼ : tilde operator */, 8773 - /* ≅ : congruent to */, 8776 - /* ≈ : almost equal to */, 8800 - /* ≠ : not equal to */, 8801 - /* ≡ : identical to, equivalent to */, 8804 - /* ≤ : less-than or equal to */, 8805 - /* ≥ : greater-than or equal to */, 8834 - /* ⊂ : subset of */, 8835 - /* ⊃ : superset of */, 8836 - /* ⊄ : not a subset of */, 8838 - /* ⊆ : subset of or equal to */, 8839 - /* ⊇ : superset of or equal to */, 8853 - /* ⊕ : circled plus */, 8855 - /* ⊗ : circled times */, 8869 - /* ⊥ : up tack */, 8901 - /* ⋅ : dot operator */, 8968 - /* ⌈ : left ceiling */, 8969 - /* ⌉ : right ceiling */, 8970 - /* ⌊ : left floor */, 8971 - /* ⌋ : right floor */, 9001 - /* ⟨ : left-pointing angle bracket */, 9002 - /* ⟩ : right-pointing angle bracket */, 9674 - /* ◊ : lozenge */, 9824 - /* ♠ : black spade suit */, 9827 - /* ♣ : black club suit */, 9829 - /* ♥ : black heart suit */, 9830 - /* ♦ : black diamond suit */, }; - characterToEntityMap = new HashMap(entityNames.length); - entityToCharacterMap = new HashMap(entityValues.length); - for (int i = 0; i < entityNames.length; i++) { - String e = entityNames[i]; - Character c = new Character(entityValues[i]); - entityToCharacterMap.put(e, c); - characterToEntityMap.put(c, e); - } - } - -} \ No newline at end of file diff --git a/src/org/owasp/esapi/codecs/JavaScriptCodec.java b/src/org/owasp/esapi/codecs/JavaScriptCodec.java deleted file mode 100644 index fc0f13e3d..000000000 --- a/src/org/owasp/esapi/codecs/JavaScriptCodec.java +++ /dev/null @@ -1,183 +0,0 @@ -/** - * 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.codecs; - - -/** - * Implementation of the Codec interface for backslash encoding frequently used in JavaScript. - * - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security - * @since June 1, 2007 - * @see org.owasp.esapi.Encoder - */ -public class JavaScriptCodec implements Codec { - - public JavaScriptCodec() { - } - - public String encode( String input ) { - StringBuffer sb = new StringBuffer(); - for ( int i=0; ihttp://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.codecs; - - - -/** - * 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. - * - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security - * @since June 1, 2007 - * @see org.owasp.esapi.Encoder - */ -public class MySQLCodec implements Codec { - - public static final int MYSQL_MODE = 0; - public static final int ANSI_MODE = 1; - - private int mode = 0; - - public MySQLCodec( int mode ) { - this.mode = mode; - } - - public String encode( String input ) { - StringBuffer sb = new StringBuffer(); - for ( int i=0; ihttp://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.codecs; - - - -/** - * 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. - * - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security - * @since June 1, 2007 - * @see org.owasp.esapi.Encoder - */ -public class OracleCodec implements Codec { - - public OracleCodec() { - } - - public String encode( String input ) { - StringBuffer sb = new StringBuffer(); - for ( int i=0; ihttp://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.codecs; - - -/** - * Implementation of the Codec interface for percent encoding (aka URL encoding). - * - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security - * @since June 1, 2007 - * @see org.owasp.esapi.Encoder - */ -public class PercentCodec implements Codec { - - public PercentCodec() { - } - - public String encode( String input ) { - return null; - } - - public String encodeCharacter( Character c ) { - return null; - } - - public String decode( String input ) { - StringBuffer sb = new StringBuffer(); - PushbackString pbs = new PushbackString( input ); - while ( pbs.hasNext() ) { - Character c = decodeCharacter( pbs ); - if ( c != null ) { - sb.append( c ); - } else { - sb.append( pbs.next() ); - } - } - return sb.toString(); - } - - /** - * 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; - */ - public Character decodeCharacter( PushbackString input ) { - input.mark(); - Character first = input.next(); - if ( first == null ) { - input.reset(); - return null; - } - - // if this is not an encoded character, return null - if ( first.charValue() != '%' ) { - input.reset(); - return null; - } - - // Search for exactly 2 hex digits following - StringBuffer sb = new StringBuffer(); - for ( int i=0; i<2; i++ ) { - Character c = input.nextHex(); - if ( c != null ) sb.append( c ); - } - if ( sb.length() == 2 ) { - try { - // parse the hex digit and create a character - int i = Integer.parseInt(sb.toString(), 16); - // TODO: in Java 1.5 you can test whether this is a valid code point - // with Character.isValidCodePoint() et al. - return new Character( (char)i ); - } catch( NumberFormatException e ) { - // throw an exception for malformed entity? - // just continue which will reset and return null - } - } - input.reset(); - return null; - } - -} \ No newline at end of file diff --git a/src/org/owasp/esapi/codecs/PushbackString.java b/src/org/owasp/esapi/codecs/PushbackString.java deleted file mode 100644 index 9e0c80abb..000000000 --- a/src/org/owasp/esapi/codecs/PushbackString.java +++ /dev/null @@ -1,119 +0,0 @@ -/** - * 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.codecs; - - -/** - * 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. - * - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security - * @since June 1, 2007 - * @see org.owasp.esapi.Encoder - */ -public class PushbackString { - - private String input; - private Character pushback; - private Character temp; - private int index = 0; - private int mark = 0; - - public PushbackString( String input ) { - this.input = input; - } - - public void pushback( Character c ) { - pushback = c; - } - - /* - * Get the current index of the PushbackString. Typically used in error messages. - */ - public int index() { - return index; - } - - public boolean hasNext() { - if ( pushback != null ) return true; - if ( input == null ) return false; - if ( input.length() == 0 ) return false; - if ( index >= input.length() ) return false; - return true; - } - - public Character next() { - if ( pushback != null ) { - Character save = pushback; - pushback = null; - return save; - } - if ( input == null ) return null; - if ( input.length() == 0 ) return null; - if ( index >= input.length() ) return null; - return new Character( input.charAt(index++) ); - } - - public Character nextHex() { - Character c = next(); - if ( c == null ) return null; - if ( isHexDigit( c ) ) return c; - return null; - } - - public boolean isHexDigit( Character c ) { - return ( "0123456789ABCDEFabcdef".indexOf( c.charValue() ) != -1 ); - } - - public Character peek() { - if ( pushback != null ) return pushback; - if ( input == null ) return null; - if ( input.length() == 0 ) return null; - if ( index >= input.length() ) return null; - return new Character( input.charAt(index) ); - } - - public boolean peek( char c ) { - if ( pushback != null && pushback.charValue() == c ) return true; - if ( input == null ) return false; - if ( input.length() == 0 ) return false; - if ( index >= input.length() ) return false; - return input.charAt(index) == c; - } - - public boolean isPushback() { - return ( pushback != null ); - } - - public void mark() { - temp = pushback; - mark = index; - } - - public void reset() { - pushback = temp; - index = mark; - } - - protected String remainder() { - String output = input.substring( index ); - if ( pushback != null ) { - output = pushback + output; - } - return output; - } -} \ No newline at end of file diff --git a/src/org/owasp/esapi/codecs/UnixCodec.java b/src/org/owasp/esapi/codecs/UnixCodec.java deleted file mode 100644 index 44606bdc1..000000000 --- a/src/org/owasp/esapi/codecs/UnixCodec.java +++ /dev/null @@ -1,88 +0,0 @@ -/** - * 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.codecs; - - -/** - * Implementation of the Codec interface for '\' encoding from Unix command shell. - * - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security - * @since June 1, 2007 - * @see org.owasp.esapi.Encoder - */ -public class UnixCodec implements Codec { - - public UnixCodec() { - } - - public String encode( String input ) { - StringBuffer sb = new StringBuffer(); - for ( int i=0; ihttp://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.codecs; - - -/** - * Implementation of the Codec interface for 'quote' encoding from VBScript. - * - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security - * @since June 1, 2007 - * @see org.owasp.esapi.Encoder - */ -public class VBScriptCodec implements Codec { - - public VBScriptCodec() { - } - - public String encode( String input ) { - StringBuffer sb = new StringBuffer(); - for ( int i=0; ihttp://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.codecs; - - -/** - * Implementation of the Codec interface for '^' encoding from Windows command shell. - * - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security - * @since June 1, 2007 - * @see org.owasp.esapi.Encoder - */ -public class WindowsCodec implements Codec { - - public WindowsCodec() { - } - - public String encode( String input ) { - StringBuffer sb = new StringBuffer(); - for ( int i=0; ihttp://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.errors; - -/** - * An AccessControlException should be thrown when a user attempts to access a - * resource that they are not authorized for. - * - * @author Jeff Williams (jeff.williams@aspectsecurity.com) - */ -public class AccessControlException extends EnterpriseSecurityException { - - /** The Constant serialVersionUID. */ - private static final long serialVersionUID = 1L; - - /** - * Instantiates a new access control exception. - */ - protected AccessControlException() { - // hidden - } - - /** - * Creates a new instance of EnterpriseSecurityException. - */ - public AccessControlException(String userMessage, String logMessage) { - super(userMessage, logMessage); - } - - /** - * Instantiates a new access control exception. - * - * @param message - * the message - * @param cause - * the cause - */ - public AccessControlException(String userMessage, String logMessage, Throwable cause) { - super(userMessage, logMessage, cause); - } - -} diff --git a/src/org/owasp/esapi/errors/AuthenticationAccountsException.java b/src/org/owasp/esapi/errors/AuthenticationAccountsException.java deleted file mode 100644 index a69a4bcdc..000000000 --- a/src/org/owasp/esapi/errors/AuthenticationAccountsException.java +++ /dev/null @@ -1,59 +0,0 @@ -/** - * 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.errors; - -/** - * An AuthenticationException should be thrown when anything goes wrong during - * login or logout. They are also appropriate for any problems related to - * identity management. - * - * @author Jeff Williams (jeff.williams@aspectsecurity.com) - */ -public class AuthenticationAccountsException extends AuthenticationException { - - /** The Constant serialVersionUID. */ - private static final long serialVersionUID = 1L; - - /** - * Instantiates a new authentication exception. - */ - protected AuthenticationAccountsException() { - // hidden - } - - /** - * Creates a new instance of EnterpriseSecurityException. - * - * @param message - * the message - */ - public AuthenticationAccountsException(String userMessage, String logMessage) { - super(userMessage, logMessage); - } - - /** - * Instantiates a new authentication exception. - * - * @param message - * the message - * @param cause - * the cause - */ - public AuthenticationAccountsException(String userMessage, String logMessage, Throwable cause) { - super(userMessage, logMessage, cause); - } - -} diff --git a/src/org/owasp/esapi/errors/AuthenticationCredentialsException.java b/src/org/owasp/esapi/errors/AuthenticationCredentialsException.java deleted file mode 100644 index 412908a24..000000000 --- a/src/org/owasp/esapi/errors/AuthenticationCredentialsException.java +++ /dev/null @@ -1,59 +0,0 @@ -/** - * 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.errors; - -/** - * An AuthenticationException should be thrown when anything goes wrong during - * login or logout. They are also appropriate for any problems related to - * identity management. - * - * @author Jeff Williams (jeff.williams@aspectsecurity.com) - */ -public class AuthenticationCredentialsException extends AuthenticationException { - - /** The Constant serialVersionUID. */ - private static final long serialVersionUID = 1L; - - /** - * Instantiates a new authentication exception. - */ - protected AuthenticationCredentialsException() { - // hidden - } - - /** - * Creates a new instance of EnterpriseSecurityException. - * - * @param message - * the message - */ - public AuthenticationCredentialsException(String userMessage, String logMessage) { - super(userMessage, logMessage); - } - - /** - * Instantiates a new authentication exception. - * - * @param message - * the message - * @param cause - * the cause - */ - public AuthenticationCredentialsException(String userMessage, String logMessage, Throwable cause) { - super(userMessage, logMessage, cause); - } - -} diff --git a/src/org/owasp/esapi/errors/AuthenticationException.java b/src/org/owasp/esapi/errors/AuthenticationException.java deleted file mode 100644 index 378887c66..000000000 --- a/src/org/owasp/esapi/errors/AuthenticationException.java +++ /dev/null @@ -1,59 +0,0 @@ -/** - * 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.errors; - -/** - * An AuthenticationException should be thrown when anything goes wrong during - * login or logout. They are also appropriate for any problems related to - * identity management. - * - * @author Jeff Williams (jeff.williams@aspectsecurity.com) - */ -public class AuthenticationException extends EnterpriseSecurityException { - - /** The Constant serialVersionUID. */ - private static final long serialVersionUID = 1L; - - /** - * Instantiates a new authentication exception. - */ - protected AuthenticationException() { - // hidden - } - - /** - * Creates a new instance of EnterpriseSecurityException. - * - * @param message - * the message - */ - public AuthenticationException(String userMessage, String logMessage) { - super(userMessage, logMessage); - } - - /** - * Instantiates a new authentication exception. - * - * @param message - * the message - * @param cause - * the cause - */ - public AuthenticationException(String userMessage, String logMessage, Throwable cause) { - super(userMessage, logMessage, cause); - } - -} diff --git a/src/org/owasp/esapi/errors/AuthenticationHostException.java b/src/org/owasp/esapi/errors/AuthenticationHostException.java deleted file mode 100644 index ec0b42bfd..000000000 --- a/src/org/owasp/esapi/errors/AuthenticationHostException.java +++ /dev/null @@ -1,58 +0,0 @@ -/** - * 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.errors; - -/** - * An AuthenticationHostException should be thrown when there is a problem with - * the host involved with authentication, particularly if the host changes unexpectedly. - * - * @author Jeff Williams (jeff.williams@aspectsecurity.com) - */ -public class AuthenticationHostException extends AuthenticationException { - - /** The Constant serialVersionUID. */ - private static final long serialVersionUID = 1L; - - /** - * Instantiates a new authentication exception. - */ - protected AuthenticationHostException() { - // hidden - } - - /** - * Creates a new instance of AuthenticationHostException. - * - * @param message - * the message - */ - public AuthenticationHostException(String userMessage, String logMessage) { - super(userMessage, logMessage); - } - - /** - * Instantiates a new authentication exception. - * - * @param message - * the message - * @param cause - * the cause - */ - public AuthenticationHostException(String userMessage, String logMessage, Throwable cause) { - super(userMessage, logMessage, cause); - } - -} diff --git a/src/org/owasp/esapi/errors/AuthenticationLoginException.java b/src/org/owasp/esapi/errors/AuthenticationLoginException.java deleted file mode 100644 index 1962ad00f..000000000 --- a/src/org/owasp/esapi/errors/AuthenticationLoginException.java +++ /dev/null @@ -1,59 +0,0 @@ -/** - * 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.errors; - -/** - * An AuthenticationException should be thrown when anything goes wrong during - * login or logout. They are also appropriate for any problems related to - * identity management. - * - * @author Jeff Williams (jeff.williams@aspectsecurity.com) - */ -public class AuthenticationLoginException extends AuthenticationException { - - /** The Constant serialVersionUID. */ - private static final long serialVersionUID = 1L; - - /** - * Instantiates a new authentication exception. - */ - protected AuthenticationLoginException() { - // hidden - } - - /** - * Creates a new instance of EnterpriseSecurityException. - * - * @param message - * the message - */ - public AuthenticationLoginException(String userMessage, String logMessage) { - super(userMessage, logMessage); - } - - /** - * Instantiates a new authentication exception. - * - * @param message - * the message - * @param cause - * the cause - */ - public AuthenticationLoginException(String userMessage, String logMessage, Throwable cause) { - super(userMessage, logMessage, cause); - } - -} diff --git a/src/org/owasp/esapi/errors/AvailabilityException.java b/src/org/owasp/esapi/errors/AvailabilityException.java deleted file mode 100644 index 6d18d1938..000000000 --- a/src/org/owasp/esapi/errors/AvailabilityException.java +++ /dev/null @@ -1,58 +0,0 @@ -/** - * 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.errors; - -/** - * 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. - * - * @author Jeff Williams (jeff.williams@aspectsecurity.com) - */ -public class AvailabilityException extends EnterpriseSecurityException { - - /** The Constant serialVersionUID. */ - private static final long serialVersionUID = 1L; - - /** - * Instantiates a new availability exception. - */ - protected AvailabilityException() { - // hidden - } - - /** - * Creates a new instance of AvailabilityException. - * - * @param message - * the message - */ - public AvailabilityException(String userMessage, String logMessage) { - super(userMessage, logMessage); - } - - /** - * Instantiates a new AvailabilityException. - * - * @param message - * the message - * @param cause - * the cause - */ - public AvailabilityException(String userMessage, String logMessage, Throwable cause) { - super(userMessage, logMessage, cause); - } -} diff --git a/src/org/owasp/esapi/errors/CertificateException.java b/src/org/owasp/esapi/errors/CertificateException.java deleted file mode 100644 index ac81c413e..000000000 --- a/src/org/owasp/esapi/errors/CertificateException.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * 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.errors; - -/** - * A CertificateException should be thrown for any problems that arise during - * processing of digital certificates. - * - * @author Jeff Williams (jeff.williams@aspectsecurity.com) - */ -public class CertificateException extends EnterpriseSecurityException { - - /** The Constant serialVersionUID. */ - private static final long serialVersionUID = 1L; - - /** - * Instantiates a new certificate exception. - */ - protected CertificateException() { - // hidden - } - - /** - * Creates a new instance of CertificateException. - * - * @param message - * the message - */ - public CertificateException(String userMessage, String logMessage) { - super(userMessage, logMessage); - } - - /** - * Instantiates a new CertificateException. - * - * @param message - * the message - * @param cause - * the cause - */ - public CertificateException(String userMessage, String logMessage, Throwable cause) { - super(userMessage, logMessage, cause); - } -} diff --git a/src/org/owasp/esapi/errors/EncodingException.java b/src/org/owasp/esapi/errors/EncodingException.java deleted file mode 100644 index 594cae96b..000000000 --- a/src/org/owasp/esapi/errors/EncodingException.java +++ /dev/null @@ -1,58 +0,0 @@ -/** - * 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.errors; - -/** - * An ExecutorException should be thrown for any problems that occur when - * encoding or decoding data. - * - * @author Jeff Williams (jeff.williams@aspectsecurity.com) - */ -public class EncodingException extends EnterpriseSecurityException { - - /** The Constant serialVersionUID. */ - private static final long serialVersionUID = 1L; - - /** - * Instantiates a new service exception. - */ - protected EncodingException() { - // hidden - } - - /** - * Creates a new instance of EncodingException. - * - * @param message - * the message - */ - public EncodingException(String userMessage, String logMessage) { - super(userMessage, logMessage); - } - - /** - * Instantiates a new EncodingException. - * - * @param message - * the message - * @param cause - * the cause - */ - public EncodingException(String userMessage, String logMessage, Throwable cause) { - super(userMessage, logMessage, cause); - } - -} diff --git a/src/org/owasp/esapi/errors/EncryptionException.java b/src/org/owasp/esapi/errors/EncryptionException.java deleted file mode 100644 index aa7068a12..000000000 --- a/src/org/owasp/esapi/errors/EncryptionException.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * 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.errors; - -/** - * An EncryptionException should be thrown for any problems related to - * encryption, hashing, or digital signatures. - * - * @author Jeff Williams (jeff.williams@aspectsecurity.com) - */ -public class EncryptionException extends EnterpriseSecurityException { - - /** The Constant serialVersionUID. */ - private static final long serialVersionUID = 1L; - - /** - * Instantiates a new EncryptionException. - */ - protected EncryptionException() { - // hidden - } - - /** - * Creates a new instance of EncryptionException. - * - * @param message - * the message - */ - public EncryptionException(String userMessage, String logMessage) { - super(userMessage, logMessage); - } - - /** - * Instantiates a new EncryptionException. - * - * @param message - * the message - * @param cause - * the cause - */ - public EncryptionException(String userMessage, String logMessage, Throwable cause) { - super(userMessage, logMessage, cause); - } -} diff --git a/src/org/owasp/esapi/errors/EnterpriseSecurityException.java b/src/org/owasp/esapi/errors/EnterpriseSecurityException.java deleted file mode 100644 index 4fa39046a..000000000 --- a/src/org/owasp/esapi/errors/EnterpriseSecurityException.java +++ /dev/null @@ -1,88 +0,0 @@ -/** - * 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.errors; - -import org.owasp.esapi.ESAPI; -import org.owasp.esapi.Logger; - - -/** - * 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. - *

- * @author Jeff Williams (jeff.williams@aspectsecurity.com) - */ -public class EnterpriseSecurityException extends Exception { - - /** The Constant serialVersionUID. */ - private static final long serialVersionUID = 1L; - - /** The logger. */ - protected final Logger logger = ESAPI.getLogger("EnterpriseSecurityException"); - - protected String logMessage = null; - - /** - * Instantiates a new security exception. - */ - protected EnterpriseSecurityException() { - // hidden - } - - /** - * 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. - * - * @param message the message - */ - public EnterpriseSecurityException(String userMessage, String logMessage) { - super(userMessage); - this.logMessage = logMessage; - ESAPI.intrusionDetector().addException(this); - } - - /** - * Creates a new instance of EnterpriseSecurityException that includes a root cause Throwable. - * - * @param message the message - * @param cause the cause - */ - public EnterpriseSecurityException(String userMessage, String logMessage, Throwable cause) { - super(userMessage, cause); - this.logMessage = logMessage; - ESAPI.intrusionDetector().addException(this); - } - - public String getUserMessage() { - return getMessage(); - } - - public String getLogMessage() { - return logMessage; - } - -} diff --git a/src/org/owasp/esapi/errors/ExecutorException.java b/src/org/owasp/esapi/errors/ExecutorException.java deleted file mode 100644 index d9ef71263..000000000 --- a/src/org/owasp/esapi/errors/ExecutorException.java +++ /dev/null @@ -1,58 +0,0 @@ -/** - * 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.errors; - -/** - * An ExecutorException should be thrown for any problems that arise during the - * execution of a system executable. - * - * @author Jeff Williams (jeff.williams@aspectsecurity.com) - */ -public class ExecutorException extends EnterpriseSecurityException { - - /** The Constant serialVersionUID. */ - private static final long serialVersionUID = 1L; - - /** - * Instantiates a new ExecutorException. - */ - protected ExecutorException() { - // hidden - } - - /** - * Creates a new instance of ExecutorException. - * - * @param message - * the message - */ - public ExecutorException(String userMessage, String logMessage) { - super(userMessage, logMessage); - } - - /** - * Instantiates a new ExecutorException. - * - * @param message - * the message - * @param cause - * the cause - */ - public ExecutorException(String userMessage, String logMessage, Throwable cause) { - super(userMessage, logMessage, cause); - } - -} diff --git a/src/org/owasp/esapi/errors/IntegrityException.java b/src/org/owasp/esapi/errors/IntegrityException.java deleted file mode 100644 index fe40f4424..000000000 --- a/src/org/owasp/esapi/errors/IntegrityException.java +++ /dev/null @@ -1,58 +0,0 @@ -/** - * 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.errors; - -/** - * 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. - * - * @author Jeff Williams (jeff.williams@aspectsecurity.com) - */ -public class IntegrityException extends EnterpriseSecurityException { - - /** The Constant serialVersionUID. */ - private static final long serialVersionUID = 1L; - - /** - * Instantiates a new availability exception. - */ - protected IntegrityException() { - // hidden - } - - /** - * Creates a new instance of IntegrityException. - * - * @param message - * the message - */ - public IntegrityException(String userMessage, String logMessage) { - super(userMessage, logMessage); - } - - /** - * Instantiates a new IntegrityException. - * - * @param message - * the message - * @param cause - * the cause - */ - public IntegrityException(String userMessage, String logMessage, Throwable cause) { - super(userMessage, logMessage, cause); - } -} diff --git a/src/org/owasp/esapi/errors/IntrusionException.java b/src/org/owasp/esapi/errors/IntrusionException.java deleted file mode 100644 index 77b21c1a8..000000000 --- a/src/org/owasp/esapi/errors/IntrusionException.java +++ /dev/null @@ -1,79 +0,0 @@ -/** - * 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.errors; - -import org.owasp.esapi.ESAPI; -import org.owasp.esapi.Logger; - -/** - * 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. - * - * @author Jeff Williams (jeff.williams@aspectsecurity.com) - */ -public class IntrusionException extends RuntimeException { - - /** The Constant serialVersionUID. */ - private static final long serialVersionUID = 1L; - - /** The logger. */ - protected final Logger logger = ESAPI.getLogger("IntrusionException"); - - protected String logMessage = null; - - /** - * Internal classes may throw an IntrusionException to the IntrusionDetector, which generates the appropriate log - * message. - */ - private IntrusionException() { - } - - /** - * Creates a new instance of IntrusionException. - * - * @param message the message - */ - public IntrusionException(String userMessage, String logMessage) { - super(userMessage); - this.logMessage = logMessage; - logger.error(Logger.SECURITY, "INTRUSION - " + logMessage); - } - - /** - * Instantiates a new intrusion exception. - * - * @param message the message - * @param cause the cause - */ - public IntrusionException(String userMessage, String logMessage, Throwable cause) { - super(userMessage, cause); - this.logMessage = logMessage; - logger.error(Logger.SECURITY, "INTRUSION - " + logMessage, cause); - } - - public String getUserMessage() { - return getMessage(); - } - - public String getLogMessage() { - return logMessage; - } - -} diff --git a/src/org/owasp/esapi/errors/ValidationAvailabilityException.java b/src/org/owasp/esapi/errors/ValidationAvailabilityException.java deleted file mode 100644 index 5bde191e4..000000000 --- a/src/org/owasp/esapi/errors/ValidationAvailabilityException.java +++ /dev/null @@ -1,52 +0,0 @@ -/** - * 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.errors; - -/** - * @author Jeff Williams (jeff.williams@aspectsecurity.com) - */ -public class ValidationAvailabilityException extends ValidationException { - - /** The Constant serialVersionUID. */ - private static final long serialVersionUID = 1L; - - /** - * Instantiates a new validation exception. - */ - protected ValidationAvailabilityException() { - // hidden - } - - /** - * Create a new ValidationException - * @param userMessage - * @param logMessage - */ - public ValidationAvailabilityException(String userMessage, String logMessage) { - super(userMessage, logMessage); - } - - /** - * Create a new ValidationException - * @param userMessage - * @param logMessage - * @param cause - */ - public ValidationAvailabilityException(String userMessage, String logMessage, Throwable cause) { - super(userMessage, logMessage, cause); - } - -} diff --git a/src/org/owasp/esapi/errors/ValidationException.java b/src/org/owasp/esapi/errors/ValidationException.java deleted file mode 100644 index 3d227b2d8..000000000 --- a/src/org/owasp/esapi/errors/ValidationException.java +++ /dev/null @@ -1,111 +0,0 @@ -/** - * 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.errors; - -/** - * 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. - * - * @author Jeff Williams (jeff.williams@aspectsecurity.com) - */ -public class ValidationException extends EnterpriseSecurityException { - - /** The Constant serialVersionUID. */ - private static final long serialVersionUID = 1L; - - /** The UI reference that caused this ValidationException */ - private String context; - - public static long getSerialVersionUID() { - return serialVersionUID; - } - - /** - * Instantiates a new validation exception. - */ - protected ValidationException() { - // hidden - } - - /** - * Creates a new instance of ValidationException. - * - * @param message - * the message - */ - public ValidationException(String userMessage, String logMessage) { - super(userMessage, logMessage); - } - - /** - * Instantiates a new ValidationException. - * - * @param message - * the message - * @param cause - * the cause - */ - public ValidationException(String userMessage, String logMessage, Throwable cause) { - super(userMessage, logMessage, cause); - } - - /** - * Creates a new instance of ValidationException. - * - * @param message - * the message - * @param context - * the source that caused this exception - */ - public ValidationException(String userMessage, String logMessage, String context) { - super(userMessage, logMessage); - setContext(context); - } - - /** - * Instantiates a new ValidationException. - * - * @param message - * the message - * @param cause - * the cause - * @param context - * the source that caused this exception - */ - public ValidationException(String userMessage, String logMessage, Throwable cause, String context) { - super(userMessage, logMessage, cause); - setContext(context); - } - - /** - * Returns the UI reference that caused this ValidationException - * - * @return - */ - public String getContext() { - return context; - } - - /** - * Set's the UI reference that caused this ValidationException - * - * @param cause - */ - public void setContext(String context) { - this.context = context; - } -} diff --git a/src/org/owasp/esapi/errors/ValidationUploadException.java b/src/org/owasp/esapi/errors/ValidationUploadException.java deleted file mode 100644 index 7e1061eea..000000000 --- a/src/org/owasp/esapi/errors/ValidationUploadException.java +++ /dev/null @@ -1,52 +0,0 @@ -/** - * 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.errors; - -/** - * @author Jeff Williams (jeff.williams@aspectsecurity.com) - */ -public class ValidationUploadException extends ValidationException { - - /** The Constant serialVersionUID. */ - private static final long serialVersionUID = 1L; - - /** - * Instantiates a new validation exception. - */ - protected ValidationUploadException() { - // hidden - } - - /** - * Create a new ValidationException - * @param userMessage - * @param logMessage - */ - public ValidationUploadException(String userMessage, String logMessage) { - super(userMessage, logMessage); - } - - /** - * Create a new ValidationException - * @param userMessage - * @param logMessage - * @param cause - */ - public ValidationUploadException(String userMessage, String logMessage, Throwable cause) { - super(userMessage, logMessage, cause); - } - -} diff --git a/src/org/owasp/esapi/errors/package.html b/src/org/owasp/esapi/errors/package.html deleted file mode 100644 index cb35f9c0b..000000000 --- a/src/org/owasp/esapi/errors/package.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - -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. - - - diff --git a/src/org/owasp/esapi/filters/ESAPIFilter.java b/src/org/owasp/esapi/filters/ESAPIFilter.java deleted file mode 100644 index aef118222..000000000 --- a/src/org/owasp/esapi/filters/ESAPIFilter.java +++ /dev/null @@ -1,150 +0,0 @@ -/** - * 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.filters; - -import java.io.IOException; -import java.util.Arrays; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.owasp.esapi.ESAPI; -import org.owasp.esapi.Logger; -import org.owasp.esapi.errors.AuthenticationException; - -public class ESAPIFilter implements Filter { - - private final Logger logger = ESAPI.getLogger("ESAPIFilter"); - - private static final String[] obfuscate = { "password" }; - - /** - * 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. - * - * @param filterConfig - * configuration object - */ - public void init(FilterConfig filterConfig) { - if ( ESAPI.securityConfiguration().getResourceDirectory() == null ) { - String path = filterConfig.getInitParameter("resourceDirectory"); - // String path = filterConfig.getServletContext().getRealPath("/")+ "WEB-INF/resources"; - ESAPI.securityConfiguration().setResourceDirectory( path ); - } - } - - /** - * 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. - * - * @param request - * Request object to be processed - * @param response - * Response object - * @param chain - * current FilterChain - * @exception IOException - * if any occurs - * @throws ServletException - */ - public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException { - HttpServletRequest request = (HttpServletRequest) req; - HttpServletResponse response = (HttpServletResponse) resp; - ESAPI.httpUtilities().setCurrentHTTP(request, response); - - try { - // figure out who the current user is - try { - ESAPI.authenticator().login(request, response); - } catch( AuthenticationException e ) { - ESAPI.authenticator().logout(); - request.setAttribute("message", "Authentication failed"); - RequestDispatcher dispatcher = request.getRequestDispatcher("WEB-INF/login.jsp"); - dispatcher.forward(request, response); - return; - } - - // log this request, obfuscating any parameter named password - ESAPI.httpUtilities().logHTTPRequest(request, logger, Arrays.asList(obfuscate)); - - // check access to this URL - if ( !ESAPI.accessController().isAuthorizedForURL(request.getRequestURI().toString()) ) { - request.setAttribute("message", "Unauthorized" ); - RequestDispatcher dispatcher = request.getRequestDispatcher("WEB-INF/index.jsp"); - dispatcher.forward(request, response); - return; - } - - // verify if this request meets the baseline input requirements - if ( !ESAPI.validator().isValidHTTPRequest() ) { - request.setAttribute("message", "Validation error" ); - RequestDispatcher dispatcher = request.getRequestDispatcher("WEB-INF/index.jsp"); - dispatcher.forward(request, response); - return; - } - - // check for CSRF attacks - // utils.checkCSRFToken(); - - // forward this request on to the web application - chain.doFilter(request, response); - - // set up response with content type - ESAPI.httpUtilities().safeSetContentType( response ); - - // set no-cache headers on every response - // only do this if the entire site should not be cached - // otherwise you should do this strategically in your controller or actions - ESAPI.httpUtilities().setNoCacheHeaders( response ); - - } catch (Exception e) { - e.printStackTrace(); - logger.error( Logger.SECURITY, "Error in ESAPI security filter: " + e.getMessage(), e ); - request.setAttribute("message", e.getMessage() ); - - } finally { - // VERY IMPORTANT - // clear out the ThreadLocal variables in the authenticator - // some containers could possibly reuse this thread without clearing the User - ESAPI.authenticator().clearCurrent(); - ESAPI.httpUtilities().setCurrentHTTP(null, null); - } - } - - /** - * 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. - */ - public void destroy() { - // finalize - } - -} \ No newline at end of file diff --git a/src/org/owasp/esapi/filters/RequestRateThrottleFilter.java b/src/org/owasp/esapi/filters/RequestRateThrottleFilter.java deleted file mode 100644 index 9de9642be..000000000 --- a/src/org/owasp/esapi/filters/RequestRateThrottleFilter.java +++ /dev/null @@ -1,109 +0,0 @@ -/** - * 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.filters; - -import java.io.IOException; -import java.util.Date; -import java.util.Stack; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; - -/** - * Servlet filter class. - */ -public class RequestRateThrottleFilter implements Filter -{ - - private int hits = 5; - - private int period = 10; - - private static final String HITS = "hits"; - - private static final String PERIOD = "period"; - - /** - * 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. - * - * @param filterConfig - * configuration object - */ - public void init(FilterConfig filterConfig) - { - hits = Integer.parseInt(filterConfig.getInitParameter(HITS)); - period = Integer.parseInt(filterConfig.getInitParameter(PERIOD)); - } - - /** - * Checks to see if the current session has exceeded the allowed number - * of requests in the specified time period. If the threshold has been - * exceeded, then a short error message is written to the output stream and - * no further processing is done on the request. Otherwise the request is - * processed as normal. - */ - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException - { - HttpServletRequest httpRequest = (HttpServletRequest) request; - HttpSession session = httpRequest.getSession(true); - - synchronized( session ) { - Stack times = (Stack) session.getAttribute("times"); - if (times == null) - { - times = new Stack(); - times.push(new Date(0)); - session.setAttribute("times", times); - } - times.push(new Date()); - if (times.size() >= hits) - { - times.removeElementAt(0); - } - Date newest = (Date) times.get(times.size() - 1); - Date oldest = (Date) times.get(0); - long elapsed = newest.getTime() - oldest.getTime(); - if (elapsed < period * 1000) // seconds - { - response.getWriter().println("Request rate too high"); - return; - } - } - chain.doFilter(request, response); - } - - /** - * 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. - */ - public void destroy() - { - // finalize - } - -} \ No newline at end of file diff --git a/src/org/owasp/esapi/filters/SafeHTTPFilter.java b/src/org/owasp/esapi/filters/SafeHTTPFilter.java deleted file mode 100644 index ef5f56fc1..000000000 --- a/src/org/owasp/esapi/filters/SafeHTTPFilter.java +++ /dev/null @@ -1,63 +0,0 @@ -/** - * 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.filters; - -import java.io.IOException; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.owasp.esapi.ESAPI; - - -/** - * 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. - */ -public class SafeHTTPFilter implements Filter { - - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - - if (!(request instanceof HttpServletRequest)) { - chain.doFilter(request, response); - return; - } - HttpServletRequest hrequest = (HttpServletRequest)request; - HttpServletResponse hresponse = (HttpServletResponse)response; - ESAPI.httpUtilities().setCurrentHTTP(hrequest, hresponse); - chain.doFilter(new SafeRequest(hrequest), new SafeResponse(hresponse)); - } - - public void destroy() { - // no special action - } - - public void init(FilterConfig filterConfig) throws ServletException { - // no special action - } - -} diff --git a/src/org/owasp/esapi/filters/SafeRequest.java b/src/org/owasp/esapi/filters/SafeRequest.java deleted file mode 100644 index 45a9eb7cb..000000000 --- a/src/org/owasp/esapi/filters/SafeRequest.java +++ /dev/null @@ -1,680 +0,0 @@ -/** - * 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.filters; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.security.Principal; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Vector; - -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletException; -import javax.servlet.ServletInputStream; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.owasp.esapi.ESAPI; -import org.owasp.esapi.Logger; -import org.owasp.esapi.errors.AccessControlException; -import org.owasp.esapi.errors.ValidationException; - - -/** - * 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. - */ -public class SafeRequest implements HttpServletRequest { - - private HttpServletRequest request; - private final Logger logger = ESAPI.getLogger("SafeRequest"); - - /** - * Construct a safe request that overrides the default request methods with safer versions. - * @param request - */ - public SafeRequest(HttpServletRequest request) { - this.request = request; - } - - /** - * Same as HttpServletRequest, no security changes required. - */ - public Object getAttribute(String name) { - return request.getAttribute(name); - } - - /** - * Same as HttpServletRequest, no security changes required. - */ - public Enumeration getAttributeNames() { - return request.getAttributeNames(); - } - - /** - * Same as HttpServletRequest, no security changes required. - */ - public String getAuthType() { - return request.getAuthType(); - } - - /** - * Same as HttpServletRequest, no security changes required. - */ - public String getCharacterEncoding() { - return request.getCharacterEncoding(); - } - - /** - * Same as HttpServletRequest, no security changes required. - */ - public int getContentLength() { - return request.getContentLength(); - } - - /** - * Same as HttpServletRequest, no security changes required. - */ - public String getContentType() { - return request.getContentType(); - } - - /** - * Returns the context path from the HttpServletRequest after - * canonicalizing and filtering out any dangerous characters. - */ - public String getContextPath() { - String path = request.getContextPath(); - String clean = ""; - try { - clean = ESAPI.validator().getValidInput( "HTTP context path: " + path, path, "HTTPContextPath", 150, false ); - } catch (ValidationException e ) { - // already logged - } - return clean; - } - - - /** - * Returns the array of Cookies from the HttpServletRequest after - * canonicalizing and filtering out any dangerous characters. - */ - public Cookie[] getCookies() { - Cookie[] cookies = request.getCookies(); - List newCookies = new ArrayList(); - for ( int i = 0; i < cookies.length; i++ ) { - Cookie c = cookies[i]; - - // build a new clean cookie - try { - // get data from original cookie - String name = ESAPI.validator().getValidInput( "Cookie name: " + c.getName(), c.getName(), "HTTPCookieName", 150, false ); - String value = ESAPI.validator().getValidInput( "Cookie value: " + c.getValue(), c.getValue(), "HTTPCookieValue", 1000, false ); - int maxAge = c.getMaxAge(); - String domain = c.getDomain(); - String path = c.getPath(); - - Cookie n = new Cookie( name, value ); - n.setMaxAge(maxAge); - - if ( domain != null ) { - n.setDomain(ESAPI.validator().getValidInput( "Cookie domain: " + domain, domain, "HTTPHeaderValue", 200, false )); - } - if ( path != null ) { - n.setPath(ESAPI.validator().getValidInput( "Cookie path: " + path, path, "HTTPHeaderValue", 200, false )); - } - newCookies.add( n ); - } catch( ValidationException e ) { - e.printStackTrace(); - logger.warning(Logger.SECURITY, "Skipping bad cookie: " + c.getName() + "=" + c.getValue() ); - } - } - return (Cookie[])newCookies.toArray(new Cookie[newCookies.size()]); - } - - /** - * Same as HttpServletRequest, no security changes required. - */ - public long getDateHeader(String name) { - return request.getDateHeader(name); - } - - /** - * Returns the named header from the HttpServletRequest after - * canonicalizing and filtering out any dangerous characters. - */ - public String getHeader(String name) { - String value = request.getHeader(name); - String clean = ""; - try { - clean = ESAPI.validator().getValidInput( "HTTP header value: " + value, value, "HTTPHeaderValue", 150, false ); - } catch (ValidationException e ) { - // already logged - } - return clean; - } - - /** - * Returns the enumeration of header names from the HttpServletRequest after - * canonicalizing and filtering out any dangerous characters. - */ - public Enumeration getHeaderNames() { - Vector v = new Vector(); - Enumeration en = request.getHeaderNames(); - while ( en.hasMoreElements() ) { - try { - String name = (String)en.nextElement(); - String clean = ESAPI.validator().getValidInput( "HTTP header name: " + name, name, "HTTPHeaderName", 150, false ); - v.add( clean ); - } catch (ValidationException e ) { - // already logged - } - } - return v.elements(); - } - - /** - * Returns the enumeration of headers from the HttpServletRequest after - * canonicalizing and filtering out any dangerous characters. - */ - public Enumeration getHeaders(String name) { - Vector v = new Vector(); - Enumeration en = request.getHeaders(name); - while ( en.hasMoreElements() ) { - try { - String value = (String)en.nextElement(); - String clean = ESAPI.validator().getValidInput( "HTTP header value (" +name+ "): " + value, value, "HTTPHeaderValue", 150, false ); - v.add( clean ); - } catch (ValidationException e ) { - // already logged - } - } - return v.elements(); - } - - /** - * 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. - */ - public ServletInputStream getInputStream() throws IOException { - return request.getInputStream(); - } - - /** - * Same as HttpServletRequest, no security changes required. - */ - public int getIntHeader(String name) { - return request.getIntHeader(name); - } - - /** - * Same as HttpServletRequest, no security changes required. - */ - public String getLocalAddr() { - return request.getLocalAddr(); - } - - /** - * Same as HttpServletRequest, no security changes required. - */ - public Locale getLocale() { - return request.getLocale(); - } - - /** - * Same as HttpServletRequest, no security changes required. - */ - public Enumeration getLocales() { - return request.getLocales(); - } - - /** - * Same as HttpServletRequest, no security changes required. - */ - public String getLocalName() { - return request.getLocalName(); - } - - /** - * Same as HttpServletRequest, no security changes required. - */ - public int getLocalPort() { - return request.getLocalPort(); - } - - /** - * Same as HttpServletRequest, no security changes required. - */ - public String getMethod() { - return request.getMethod(); - } - - /** - * Returns the named parameter from the HttpServletRequest after - * canonicalizing and filtering out any dangerous characters. - */ - public String getParameter(String name) { - String orig = request.getParameter( name ); - String clean = ""; - try { - clean = ESAPI.validator().getValidInput( "HTTP parameter name: " + name, orig, "HTTPParameterValue", 2000, false ); - } catch (ValidationException e ) { - // already logged - } - return clean; - } - - /** - * Returns the parameter map from the HttpServletRequest after - * canonicalizing and filtering out any dangerous characters. - */ - public Map getParameterMap() { - Map map = request.getParameterMap(); - HashMap cleanMap = new HashMap(); - Iterator i = map.entrySet().iterator(); - while ( i.hasNext() ) { - try { - Map.Entry e = (Map.Entry)i.next(); - String name = (String)e.getKey(); - String cleanName = ESAPI.validator().getValidInput( "HTTP parameter name: " + name, name, "HTTPParameterName", 100, false ); - - String[] value = (String[])e.getValue(); - String[] cleanValues = new String[value.length]; - for( int j = 0; j < value.length; j++ ) { - String cleanValue = ESAPI.validator().getValidInput( "HTTP parameter value: " + value[j], value[j], "HTTPParameterValue", 2000, false ); - cleanValues[j] = cleanValue; - } - cleanMap.put( cleanName, cleanValues); - } catch( ValidationException e ) { - // already logged - } - } - return cleanMap; - } - - /** - * Returns the enumeration of parameter names from the HttpServletRequest after - * canonicalizing and filtering out any dangerous characters. - */ - public Enumeration getParameterNames() { - Vector v = new Vector(); - Enumeration en = request.getParameterNames(); - while ( en.hasMoreElements() ) { - try { - String name = (String)en.nextElement(); - String clean = ESAPI.validator().getValidInput( "HTTP parameter name: " + name, name, "HTTPParameterName", 150, false ); - v.add( clean ); - } catch (ValidationException e ) { - // already logged - } - } - return v.elements(); - } - - /** - * Returns the array of matching parameter values from the HttpServletRequest after - * canonicalizing and filtering out any dangerous characters. - */ - public String[] getParameterValues(String name) { - String[] values = request.getParameterValues(name); - List newValues = new ArrayList(); - for ( int i = 0; i < values.length; i++ ) { - try { - String value = values[i]; - String cleanValue = ESAPI.validator().getValidInput( "HTTP parameter value: " + value, value, "HTTPParameterValue", 2000, false ); - newValues.add( cleanValue ); - } catch( ValidationException e ) { - logger.warning(Logger.SECURITY, "Skipping bad parameter" ); - } - } - return (String[])newValues.toArray(); - } - - /** - * Returns the path info from the HttpServletRequest after - * canonicalizing and filtering out any dangerous characters. - */ - public String getPathInfo() { - String path = request.getPathInfo(); - String clean = ""; - try { - clean = ESAPI.validator().getValidInput( "HTTP path: " + path, path, "HTTPPath", 150, false ); - } catch (ValidationException e ) { - // already logged - } - return clean; - } - - /** - * Same as HttpServletRequest, no security changes required. - */ - public String getPathTranslated() { - return request.getPathTranslated(); - } - - /** - * Same as HttpServletRequest, no security changes required. - */ - public String getProtocol() { - return request.getProtocol(); - } - - /** - * Returns the query string from the HttpServletRequest after - * canonicalizing and filtering out any dangerous characters. - */ - public String getQueryString() { - String query = request.getQueryString(); - String clean = ""; - try { - clean = ESAPI.validator().getValidInput( "HTTP query string: " + query, query, "HTTPQueryString", 2000, false ); - } catch (ValidationException e ) { - // already logged - } - return clean; - } - - /** - * 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. - */ - public BufferedReader getReader() throws IOException { - return request.getReader(); - } - - /** - * Same as HttpServletRequest, no security changes required. - */ - public String getRealPath(String path) { - return request.getRealPath(path); - } - - /** - * Same as HttpServletRequest, no security changes required. - */ - public String getRemoteAddr() { - return request.getRemoteAddr(); - } - - /** - * Same as HttpServletRequest, no security changes required. - */ - public String getRemoteHost() { - return request.getRemoteHost(); - } - - /** - * Same as HttpServletRequest, no security changes required. - */ - public int getRemotePort() { - return request.getRemotePort(); - } - - /** - * Returns the name of the ESAPI user associated with this request. - */ - public String getRemoteUser() { - return ESAPI.authenticator().getCurrentUser().getAccountName(); - } - - /** - * Checks to make sure the path to forward to is within the WEB-INF directory - * and then returns the dispatcher. Otherwise returns null. - */ - public RequestDispatcher getRequestDispatcher(String path) { - if (path.startsWith("WEB-INF")) { - return request.getRequestDispatcher(path); - } - return null; - } - - /** - * 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. - */ - public String getRequestedSessionId() { - String id = request.getRequestedSessionId(); - String clean = ""; - try { - clean = ESAPI.validator().getValidInput( "Requested cookie: " + id, id, "HTTPJSESSIONID", 50, false ); - } catch (ValidationException e ) { - // already logged - } - return clean; - } - - /** - * Returns the URI from the HttpServletRequest after - * canonicalizing and filtering out any dangerous characters. - */ - public String getRequestURI() { - String uri = request.getRequestURI(); - String clean = ""; - try { - clean = ESAPI.validator().getValidInput( "HTTP URI: " + uri, uri, "HTTPURI", 2000, false ); - } catch (ValidationException e ) { - // already logged - } - return clean; - } - - /** - * Returns the URL from the HttpServletRequest after - * canonicalizing and filtering out any dangerous characters. - */ - public StringBuffer getRequestURL() { - String url = request.getRequestURL().toString(); - String clean = ""; - try { - clean = ESAPI.validator().getValidInput( "HTTP URL: " + url, url, "HTTPURL", 2000, false ); - } catch (ValidationException e ) { - // already logged - } - return new StringBuffer( clean ); - } - - /** - * Returns the scheme from the HttpServletRequest after - * canonicalizing and filtering out any dangerous characters. - */ - public String getScheme() { - String scheme = request.getScheme(); - String clean = ""; - try { - clean = ESAPI.validator().getValidInput( "HTTP scheme: " + scheme, scheme, "HTTPScheme", 10, false ); - } catch (ValidationException e ) { - // already logged - } - return clean; - } - - /** - * Returns the server name (host header) from the HttpServletRequest after - * canonicalizing and filtering out any dangerous characters. - */ - public String getServerName() { - String name = request.getServerName(); - String clean = ""; - try { - clean = ESAPI.validator().getValidInput( "HTTP server name: " + name, name, "HTTPServerName", 100, false ); - } catch (ValidationException e ) { - // already logged - } - return clean; - } - - /** - * Returns the server port (after the : in the host header) from the HttpServletRequest after - * parsing and checking the range 0-65536. - */ - public int getServerPort() { - int port = request.getServerPort(); - if ( port < 0 || port > 0xFFFF ) { - logger.warning( Logger.SECURITY, "HTTP server port out of range: " + port ); - port = 0; - } - return port; - } - - /** - * Returns the server path from the HttpServletRequest after - * canonicalizing and filtering out any dangerous characters. - */ - public String getServletPath() { - String path = request.getServletPath(); - String clean = ""; - try { - clean = ESAPI.validator().getValidInput( "HTTP servlet path: " + path, path, "HTTPServletPath", 100, false ); - } catch (ValidationException e ) { - // already logged - } - return clean; - } - - /** - * Returns a session, creating it if necessary, and sets the HttpOnly flag on the JSESSIONID cookie. - */ - public HttpSession getSession() { - HttpSession session = request.getSession(); - - // send a new cookie header with HttpOnly on first and second responses - if ( session.getAttribute("HTTP_ONLY") == null ) { - session.setAttribute("HTTP_ONLY", "set" ); - Cookie cookie=new Cookie("JSESSIONID", session.getId()); - cookie.setMaxAge(-1); // session cookie - HttpServletResponse response = ESAPI.currentResponse(); - if ( response != null ) { - ESAPI.currentResponse().addCookie(cookie); - } - } - - return session; - } - - /** - * Returns a session, creating it if necessary, and sets the HttpOnly flag on the JSESSIONID cookie. - */ - public HttpSession getSession(boolean create) { - HttpSession session = request.getSession( create ); - if ( session == null ) { - return null; - } - // send a new cookie header with HttpOnly on first and second responses - if ( session.getAttribute("HTTP_ONLY") == null ) { - session.setAttribute("HTTP_ONLY", "set" ); - Cookie cookie=new Cookie("JSESSIONID", session.getId()); - cookie.setMaxAge(-1); // session cookie - HttpServletResponse response = ESAPI.currentResponse(); - if ( response != null ) { - ESAPI.currentResponse().addCookie(cookie); - } - } - - return session; - } - - /** - * Returns the ESAPI User associated with this request. - */ - public Principal getUserPrincipal() { - return ESAPI.authenticator().getCurrentUser(); - } - - /** - * Same as HttpServletRequest, no security changes required. - */ - public boolean isRequestedSessionIdFromCookie() { - return request.isRequestedSessionIdFromCookie(); - } - - /** - * Same as HttpServletRequest, no security changes required. - */ - public boolean isRequestedSessionIdFromUrl() { - return request.isRequestedSessionIdFromUrl(); - } - - /** - * Same as HttpServletRequest, no security changes required. - */ - public boolean isRequestedSessionIdFromURL() { - return request.isRequestedSessionIdFromURL(); - } - - /** - * Same as HttpServletRequest, no security changes required. - */ - public boolean isRequestedSessionIdValid() { - return request.isRequestedSessionIdValid(); - } - - /** - * Same as HttpServletRequest, no security changes required. - */ - public boolean isSecure() { - // TODO Check request method to see if this is vulnerable - return request.isSecure(); - } - - /** - * Returns true if the ESAPI User associated with this request has the specified role. - */ - public boolean isUserInRole(String role) { - return ESAPI.authenticator().getCurrentUser().isInRole(role); - } - - /** - * Same as HttpServletRequest, no security changes required. - */ - public void removeAttribute(String name) { - request.removeAttribute(name); - } - - /** - * Same as HttpServletRequest, no security changes required. - */ - public void setAttribute(String name, Object o) { - request.setAttribute(name, o); - } - - /** - * Sets the character encoding to the ESAPI configured encoding. - */ - public void setCharacterEncoding(String enc) throws UnsupportedEncodingException { - request.setCharacterEncoding( ESAPI.securityConfiguration().getCharacterEncoding() ); - } - -} - diff --git a/src/org/owasp/esapi/filters/SafeResponse.java b/src/org/owasp/esapi/filters/SafeResponse.java deleted file mode 100644 index e4def54d2..000000000 --- a/src/org/owasp/esapi/filters/SafeResponse.java +++ /dev/null @@ -1,419 +0,0 @@ -/** - * 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.filters; - -import java.io.IOException; -import java.io.PrintWriter; -import java.util.Locale; - -import javax.servlet.ServletOutputStream; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletResponse; - -import org.owasp.esapi.ESAPI; -import org.owasp.esapi.Logger; -import org.owasp.esapi.StringUtilities; -import org.owasp.esapi.errors.ValidationException; - -/** - * This response wrapper simply overrides unsafe methods in the - * HttpServletResponse API with safe versions. - */ -public class SafeResponse implements HttpServletResponse { - - private HttpServletResponse response; - private final Logger logger = ESAPI.getLogger("SafeResponse"); - - /** - * Construct a safe response that overrides the default response methods - * with safer versions. - * - * @param response - */ - public SafeResponse(HttpServletResponse response) { - this.response = response; - } - - /** - * 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. - */ - public void addCookie(Cookie cookie) { - String name = cookie.getName(); - String value = cookie.getValue(); - int maxAge = cookie.getMaxAge(); - String domain = cookie.getDomain(); - String path = cookie.getPath(); - addCookie(name, value, maxAge, domain, path); - } - - /** - * 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. - */ - public void addCookie(String name, String value, int maxAge, String domain, - String path) { - try { - String cookieName = ESAPI.validator().getValidInput( - "safeAddCookie", name, "HTTPCookieName", 50, false); - String cookieValue = ESAPI.validator().getValidInput( - "safeAddCookie", value, "HTTPCookieValue", 5000, false); - - // create the special cookie header - // Set-Cookie:=[; =][; expires=][; - // domain=][; path=][; secure][;HttpOnly - String header = cookieName + "=" + cookieValue; - if (maxAge != -1) - header += "; Max-Age=" + maxAge; - if (domain != null) - header += "; Domain=" + domain; - if (path != null) - header += "; Path=" + path; - header += "; Secure; HttpOnly"; - response.addHeader("Set-Cookie", header); - - } catch (ValidationException e) { - logger.warning(Logger.SECURITY, - "Attempt to set invalid cookie denied", e); - } - } - - /** - * Add a cookie to the response after ensuring that there are no encoded or - * illegal characters in the name. - */ - public void addDateHeader(String name, long date) { - try { - String safeName = ESAPI.validator().getValidInput( "safeSetDateHeader", name, "HTTPHeaderName", 20, false); - response.addDateHeader(safeName, date); - } catch (ValidationException e) { - logger.warning(Logger.SECURITY, "Attempt to set invalid date header name denied", e); - } - } - - /** - * 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 - */ - public void addHeader(String name, String value) { - try { - // TODO: make stripping a global config - String strippedName = StringUtilities.stripControls(name); - String strippedValue = StringUtilities.stripControls(value); - String safeName = ESAPI.validator().getValidInput("addHeader", strippedName, "HTTPHeaderName", 20, false); - String safeValue = ESAPI.validator().getValidInput("addHeader", strippedValue, "HTTPHeaderValue", 500, false); - response.setHeader(safeName, safeValue); - } catch (ValidationException e) { - logger.warning(Logger.SECURITY, "Attempt to add invalid header denied", e); - } - } - - /** - * Add an int header to the response after ensuring that there are no - * encoded or illegal characters in the name and name. - */ - public void addIntHeader(String name, int value) { - try { - String safeName = ESAPI.validator().getValidInput( "safeSetDateHeader", name, "HTTPHeaderName", 20, false); - response.addIntHeader(safeName, value); - } catch (ValidationException e) { - logger.warning(Logger.SECURITY, "Attempt to set invalid int header name denied", e); - } - } - - /** - * Same as HttpServletResponse, no security changes required. - */ - public boolean containsHeader(String name) { - return response.containsHeader(name); - } - - /** - * 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. - * - * @param url - * @return original url - */ - public String encodeRedirectUrl(String url) { - return 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. This - * exposes the JSESSIONID credential in bookmarks, referer headers, server - * logs, and more. - * - * @param url - * @return original url - */ - public String encodeRedirectURL(String url) { - return 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. This - * exposes the JSESSIONID credential in bookmarks, referer headers, server - * logs, and more. - * - * @param url - * @return original url - */ - public String encodeUrl(String url) { - return 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. This - * exposes the JSESSIONID credential in bookmarks, referer headers, server - * logs, and more. - * - * @param url - * @return original url - */ - public String encodeURL(String url) { - return url; - } - - /** - * Same as HttpServletResponse, no security changes required. - */ - public void flushBuffer() throws IOException { - response.flushBuffer(); - } - - /** - * Same as HttpServletResponse, no security changes required. - */ - public int getBufferSize() { - return response.getBufferSize(); - } - - /** - * Same as HttpServletResponse, no security changes required. - */ - public String getCharacterEncoding() { - return response.getCharacterEncoding(); - } - - /** - * Same as HttpServletResponse, no security changes required. - */ - public String getContentType() { - return response.getContentType(); - } - - /** - * Same as HttpServletResponse, no security changes required. - */ - public Locale getLocale() { - return response.getLocale(); - } - - /** - * Same as HttpServletResponse, no security changes required. - */ - public ServletOutputStream getOutputStream() throws IOException { - return response.getOutputStream(); - } - - /** - * Same as HttpServletResponse, no security changes required. - */ - public PrintWriter getWriter() throws IOException { - return response.getWriter(); - } - - /** - * Same as HttpServletResponse, no security changes required. - */ - public boolean isCommitted() { - return response.isCommitted(); - } - - /** - * Same as HttpServletResponse, no security changes required. - */ - public void reset() { - response.reset(); - } - - /** - * Same as HttpServletResponse, no security changes required. - */ - public void resetBuffer() { - response.resetBuffer(); - } - - /** - * Override the error code with a 200 in order to confound attackers using - * automated scanners. - */ - public void sendError(int sc) throws IOException { - response.sendError(HttpServletResponse.SC_OK, getHTTPMessage(sc)); - } - - /** - * Override the error code with a 200 in order to confound attackers using - * automated scanners. The message is canonicalized and filtered for - * dangerous characters. - */ - public void sendError(int sc, String msg) throws IOException { - response.sendError(HttpServletResponse.SC_OK, ESAPI.encoder().encodeForHTML(msg)); - } - - - - /** - * 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. - */ - public void sendRedirect(String location) throws IOException { - if (!ESAPI.validator().isValidRedirectLocation("Redirect", location, false)) { - logger.fatal(Logger.SECURITY, "Bad redirect location: " + location ); - throw new IOException("Redirect failed"); - } - response.sendRedirect(location); - } - - /** - * Same as HttpServletResponse, no security changes required. - */ - public void setBufferSize(int size) { - response.setBufferSize(size); - } - - /** - * Sets the character encoding to the ESAPI configured encoding. - */ - public void setCharacterEncoding(String charset) { - response.setCharacterEncoding( ESAPI.securityConfiguration().getCharacterEncoding() ); - } - - /** - * Same as HttpServletResponse, no security changes required. - */ - public void setContentLength(int len) { - response.setContentLength(len); - } - - /** - * Same as HttpServletResponse, no security changes required. - */ - public void setContentType(String type) { - response.setContentType(type); - } - - /** - * Add a date header to the response after ensuring that there are no - * encoded or illegal characters in the name. - */ - public void setDateHeader(String name, long date) { - try { - String safeName = ESAPI.validator().getValidInput( "safeSetDateHeader", name, "HTTPHeaderName", 20, false); - response.setDateHeader(safeName, date); - } catch (ValidationException e) { - logger.warning(Logger.SECURITY, "Attempt to set invalid date header name denied", e); - } - } - - /** - * 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 - */ - public void setHeader(String name, String value) { - try { - String strippedName = StringUtilities.stripControls(name); - String strippedValue = StringUtilities.stripControls(value); - String safeName = ESAPI.validator().getValidInput("setHeader", strippedName, "HTTPHeaderName", 20, false); - String safeValue = ESAPI.validator().getValidInput("setHeader", strippedValue, "HTTPHeaderValue", 500, false); - response.setHeader(safeName, safeValue); - } catch (ValidationException e) { - logger.warning(Logger.SECURITY, "Attempt to set invalid header denied", e); - } - } - - /** - * Add an int header to the response after ensuring that there are no - * encoded or illegal characters in the name. - */ - public void setIntHeader(String name, int value) { - try { - String safeName = ESAPI.validator().getValidInput( "safeSetDateHeader", name, "HTTPHeaderName", 20, false); - response.setIntHeader(safeName, value); - } catch (ValidationException e) { - logger.warning(Logger.SECURITY, "Attempt to set invalid int header name denied", e); - } - } - - /** - * Same as HttpServletResponse, no security changes required. - */ - public void setLocale(Locale loc) { - // TODO investigate the character set issues here - response.setLocale(loc); - } - - /** - * Override the status code with a 200 in order to confound attackers using - * automated scanners. - */ - public void setStatus(int sc) { - response.setStatus(HttpServletResponse.SC_OK); - } - - /** - * Override the status code with a 200 in order to confound attackers using - * automated scanners. The message is canonicalized and filtered for - * dangerous characters. - */ - public void setStatus(int sc, String sm) { - try { - // setStatus is deprecated so use sendError instead - sendError(HttpServletResponse.SC_OK, sm); - } catch (IOException e) { - logger.warning(Logger.SECURITY, "Attempt to set response status failed", e); - } - } - - /** - * returns a text message for the HTTP response code - */ - private String getHTTPMessage(int sc) { - return "HTTP error code: " + sc; - } - -} diff --git a/src/org/owasp/esapi/package.html b/src/org/owasp/esapi/package.html deleted file mode 100644 index 82cb394c4..000000000 --- a/src/org/owasp/esapi/package.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - -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: - - - - diff --git a/src/org/owasp/esapi/reference/DefaultEncoder.java b/src/org/owasp/esapi/reference/DefaultEncoder.java deleted file mode 100644 index 20a1e592a..000000000 --- a/src/org/owasp/esapi/reference/DefaultEncoder.java +++ /dev/null @@ -1,593 +0,0 @@ -/** - * 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.reference; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; - -import org.owasp.esapi.ESAPI; -import org.owasp.esapi.Logger; -import org.owasp.esapi.codecs.Base64; -import org.owasp.esapi.codecs.CSSCodec; -import org.owasp.esapi.codecs.Codec; -import org.owasp.esapi.codecs.HTMLEntityCodec; -import org.owasp.esapi.codecs.JavaScriptCodec; -import org.owasp.esapi.codecs.PercentCodec; -import org.owasp.esapi.codecs.PushbackString; -import org.owasp.esapi.codecs.VBScriptCodec; -import org.owasp.esapi.errors.EncodingException; -import org.owasp.esapi.errors.IntrusionException; - -import sun.text.Normalizer; - -/** - * 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
  • - *
- * - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security - * @since June 1, 2007 - * @see org.owasp.esapi.Encoder - */ -public class DefaultEncoder implements org.owasp.esapi.Encoder { - - // Codecs - List codecs = new ArrayList(); - private HTMLEntityCodec htmlCodec = new HTMLEntityCodec(); - private PercentCodec percentCodec = new PercentCodec(); - private JavaScriptCodec javaScriptCodec = new JavaScriptCodec(); - private VBScriptCodec vbScriptCodec = new VBScriptCodec(); - private CSSCodec cssCodec = new CSSCodec(); - - /** The logger. */ - private final Logger logger = ESAPI.getLogger("Encoder"); - - /** Character sets that define characters immune from encoding in various formats */ - private final static char[] IMMUNE_HTML = { ',', '.', '-', '_', ' ' }; - private final static char[] IMMUNE_HTMLATTR = { ',', '.', '-', '_' }; - private final static char[] IMMUNE_CSS = { ' ' }; // TODO: check - private final static char[] IMMUNE_JAVASCRIPT = { ',', '.', '-', '_', ' ' }; - private final static char[] IMMUNE_VBSCRIPT = { ' ' }; // TODO: check - private final static char[] IMMUNE_XML = { ',', '.', '-', '_', ' ' }; - private final static char[] IMMUNE_SQL = { ' ' }; - private final static char[] IMMUNE_OS = {}; - private final static char[] IMMUNE_XMLATTR = { ',', '.', '-', '_' }; - private final static char[] IMMUNE_XPATH = { ',', '.', '-', '_', ' ' }; - - - public DefaultEncoder() { - // initialize the codec list to use for canonicalization - codecs.add( htmlCodec ); - codecs.add( percentCodec ); - codecs.add( javaScriptCodec ); - - // leave this out because it eats / characters - // codecs.add( cssCodec ); - - // leave this out because it eats " characters - // codecs.add( vbScriptCodec ); - - Arrays.sort( DefaultEncoder.IMMUNE_HTML ); - Arrays.sort( DefaultEncoder.IMMUNE_HTMLATTR ); - Arrays.sort( DefaultEncoder.IMMUNE_JAVASCRIPT ); - Arrays.sort( DefaultEncoder.IMMUNE_VBSCRIPT ); - Arrays.sort( DefaultEncoder.IMMUNE_XML ); - Arrays.sort( DefaultEncoder.IMMUNE_XMLATTR ); - Arrays.sort( DefaultEncoder.IMMUNE_XPATH ); - Arrays.sort( DefaultEncoder.CHAR_LOWERS ); - Arrays.sort( DefaultEncoder.CHAR_UPPERS ); - Arrays.sort( DefaultEncoder.CHAR_DIGITS ); - Arrays.sort( DefaultEncoder.CHAR_SPECIALS ); - Arrays.sort( DefaultEncoder.CHAR_LETTERS ); - Arrays.sort( DefaultEncoder.CHAR_ALPHANUMERICS ); - Arrays.sort( DefaultEncoder.CHAR_PASSWORD_LOWERS ); - Arrays.sort( DefaultEncoder.CHAR_PASSWORD_UPPERS ); - Arrays.sort( DefaultEncoder.CHAR_PASSWORD_DIGITS ); - Arrays.sort( DefaultEncoder.CHAR_PASSWORD_SPECIALS ); - Arrays.sort( DefaultEncoder.CHAR_PASSWORD_LETTERS ); - } - - /** - * 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 - * - *
-	 * &lt;
-	 * 
- * - * or - * - *
-	 * %26lt;
-	 * 
- * - * or - * - *
-	 * &lt;
-	 * 
. - * - * 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. - * - * @throws IntrusionException - * @see org.owasp.esapi.Validator#canonicalize(java.lang.String) - */ - public String canonicalize( String input ) { - if ( input == null ) return null; - return canonicalize( input, true ); - } - - /** - * Strict mode throws an exception when any double encoded data is detected. - */ - public String canonicalize( String input, boolean strict ) { - if ( input == null ) return null; - String candidate = canonicalizeOnce( input ); - String canary = canonicalizeOnce( candidate ); - if ( !candidate.equals( canary ) ) { - if ( strict ) { - throw new IntrusionException( "Input validation failure", "Double encoding detected in " + input ); - } else { - logger.warning( Logger.SECURITY, "Double encoding detected in " + input ); - } - } - return candidate; - } - - private String canonicalizeOnce( String input ) { - if ( input == null ) return null; - StringBuffer sb = new StringBuffer(); - PushbackString pbs = new PushbackString( input ); - while ( pbs.hasNext() ) { - // test for encoded character and pushback if found - boolean encoded = decodeNext( pbs ); - - // get the next character and do something with it - Character ch = pbs.next(); - - // if an encoded character is found, push it back - if ( encoded ) { - pbs.pushback( ch ); - } else { - sb.append( ch ); - } - } - return sb.toString(); - } - - /** - * Helper method to iterate through codecs to see if the current character - * is an encoded character in any of them. If the current character is - * encoded, then it is decoded and pushed back onto the string, and this - * method returns true. If the current character is not encoded, then the - * pushback stream is reset to its original state and this method returns false. - */ - private boolean decodeNext( PushbackString pbs ) { - Iterator i = codecs.iterator(); - pbs.mark(); - while ( i.hasNext() ) { - pbs.reset(); - Codec codec = (Codec)i.next(); - Character decoded = codec.decodeCharacter(pbs); - if ( decoded != null ) { - pbs.pushback( decoded ); - return true; - } - } - pbs.reset(); - return false; - } - - - /** - * 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. - * - * @see org.owasp.esapi.Validator#normalize(java.lang.String) - */ - public String normalize(String input) { - // Split any special characters into two parts, the base character and - // the modifier - - String separated = Normalizer.normalize(input, Normalizer.DECOMP, 0); // Java 1.4 - // String separated = Normalizer.normalize(input, Form.NFD); // Java 1.6 - - // remove any character that is not ASCII - return separated.replaceAll("[^\\p{ASCII}]", ""); - } - - - /** - * Encoding utility method. It is strongly recommended that you - * canonicalize input before calling this method to prevent double-encoding. - */ - private String encode( char c, Codec codec, char[] baseImmune, char[] specialImmune ) { - if (isContained(baseImmune, c) || isContained(specialImmune, c)) { - return ""+c; - } else { - return codec.encodeCharacter( new Character( c ) ); - } - } - - - - /** - * 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 - * @see org.owasp.esapi.Encoder#encodeForHTML(java.lang.String) - */ - public String encodeForHTML(String input) { - if( input == null ) return null; - StringBuffer sb = new StringBuffer(); - for ( int i=0; i= 0x7f && c <= 0x9f ) ) { - logger.warning( Logger.SECURITY, "Attempt to HTML entity encode illegal character: " + (int)c + " (skipping)" ); - } else { - sb.append( encode( c, htmlCodec, CHAR_ALPHANUMERICS, IMMUNE_HTML ) ); - } - } - return sb.toString(); - } - - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.Encoder#encodeForHTMLAttribute(java.lang.String) - */ - public String encodeForHTMLAttribute(String input) { - if( input == null ) return null; - StringBuffer sb = new StringBuffer(); - for ( int i=0; i 0) && ((input.charAt(0) == ' ') || (input.charAt(0) == '#'))) { - sb.append('\\'); // add the leading backslash if needed - } - for (int i = 0; i < input.length(); i++) { - char c = input.charAt(i); - switch (c) { - case '\\': - sb.append("\\\\"); - break; - case ',': - sb.append("\\,"); - break; - case '+': - sb.append("\\+"); - break; - case '"': - sb.append("\\\""); - break; - case '<': - sb.append("\\<"); - break; - case '>': - sb.append("\\>"); - break; - case ';': - sb.append("\\;"); - break; - default: - sb.append(c); - } - } - // add the trailing backslash if needed - if ((input.length() > 1) && (input.charAt(input.length() - 1) == ' ')) { - sb.insert(sb.length() - 1, '\\'); - } - return sb.toString(); - } - - /** - * 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. - * - * @param input - * the input - * @return the string - * @see org.owasp.esapi.Encoder#encodeForXPath(java.lang.String) - */ - public String encodeForXPath(String input) { - if( input == null ) return null; - StringBuffer sb = new StringBuffer(); - for ( int i=0; i= 0 ); - } - - -} \ No newline at end of file diff --git a/src/org/owasp/esapi/reference/DefaultEncryptedProperties.java b/src/org/owasp/esapi/reference/DefaultEncryptedProperties.java deleted file mode 100644 index aa9183eeb..000000000 --- a/src/org/owasp/esapi/reference/DefaultEncryptedProperties.java +++ /dev/null @@ -1,170 +0,0 @@ -/** - * 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.reference; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.util.Iterator; -import java.util.Properties; -import java.util.Set; - -import org.owasp.esapi.ESAPI; -import org.owasp.esapi.Logger; -import org.owasp.esapi.errors.EncryptionException; - -/** - * 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. - * - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security - * @since June 1, 2007 - * @see org.owasp.esapi.EncryptedProperties - */ -public class DefaultEncryptedProperties implements org.owasp.esapi.EncryptedProperties { - - /** The properties. */ - private final Properties properties = new Properties(); - - /** The logger. */ - private final Logger logger = ESAPI.getLogger("EncryptedProperties"); - - /** - * Instantiates a new encrypted properties. - */ - public DefaultEncryptedProperties() { - // hidden - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IEncryptedProperties#getProperty(java.lang.String) - */ - public synchronized String getProperty(String key) throws EncryptionException { - try { - return ESAPI.encryptor().decrypt(properties.getProperty(key)); - } catch (Exception e) { - throw new EncryptionException("Property retrieval failure", "Couldn't decrypt property", e); - } - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IEncryptedProperties#setProperty(java.lang.String, - * java.lang.String) - */ - public synchronized String setProperty(String key, String value) throws EncryptionException { - try { - return (String)properties.setProperty(key, ESAPI.encryptor().encrypt(value)); - } catch (Exception e) { - throw new EncryptionException("Property setting failure", "Couldn't encrypt property", e); - } - } - - /** - * Key set. - * - * @return the set - */ - public Set keySet() { - return properties.keySet(); - } - - /** - * Load. - * - * @param in - * the in - * - * @throws IOException - * Signals that an I/O exception has occurred. - */ - public void load(InputStream in) throws IOException { - properties.load(in); - logger.trace(Logger.SECURITY, "Encrypted properties loaded successfully"); - } - - /** - * Store. - * - * @param out - * the out - * @param comments - * the comments - * - * @throws IOException - * Signals that an I/O exception has occurred. - */ - public void store(OutputStream out, String comments) throws IOException { - properties.store(out, comments); - } - - /** - * The main method. - * - * @param args - * the arguments - * - * @throws Exception - * the exception - */ - public static void main(String[] args) throws Exception { - File f = new File(args[0]); - ESAPI.getLogger( "EncryptedProperties.main" ).debug(Logger.SECURITY, "Loading encrypted properties from " + f.getAbsolutePath() ); - if ( !f.exists() ) throw new IOException( "Properties file not found: " + f.getAbsolutePath() ); - ESAPI.getLogger( "EncryptedProperties.main" ).debug(Logger.SECURITY, "Encrypted properties found in " + f.getAbsolutePath() ); - DefaultEncryptedProperties ep = new DefaultEncryptedProperties(); - FileInputStream in = new FileInputStream(f); - ep.load(in); - - BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); - String key = null; - do { - System.out.print("Enter key: "); - key = br.readLine(); - System.out.print("Enter value: "); - String value = br.readLine(); - if (key != null && key.length() > 0 && value != null && value.length() > 0) { - ep.setProperty(key, value); - } - } while (key != null && key.length() > 0); - - FileOutputStream out = new FileOutputStream(f); - ep.store(out, "Encrypted Properties File"); - out.close(); - - Iterator i = ep.keySet().iterator(); - while (i.hasNext()) { - String k = (String) i.next(); - String value = ep.getProperty(k); - System.out.println(" " + k + "=" + value); - } - } - -} diff --git a/src/org/owasp/esapi/reference/DefaultExecutor.java b/src/org/owasp/esapi/reference/DefaultExecutor.java deleted file mode 100644 index f924cb144..000000000 --- a/src/org/owasp/esapi/reference/DefaultExecutor.java +++ /dev/null @@ -1,118 +0,0 @@ -/** - * 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.reference; - -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.List; - -import org.owasp.esapi.ESAPI; -import org.owasp.esapi.Logger; -import org.owasp.esapi.Validator; -import org.owasp.esapi.codecs.Codec; -import org.owasp.esapi.errors.ExecutorException; - -/** - * 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. - * - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security - * @since June 1, 2007 - * @see org.owasp.esapi.Executor - */ -public class DefaultExecutor implements org.owasp.esapi.Executor { - - /** The logger. */ - private final Logger logger = ESAPI.getLogger("Executor"); - - private final int MAX_SYSTEM_COMMAND_LENGTH = 2500; - - - public DefaultExecutor() { - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.Executor#executeSystemCommand(java.lang.String, java.util.List, java.io.File, - * org.owasp.esapi.codecs.Codec) - */ - public String executeSystemCommand(File executable, List params, File workdir, Codec codec) throws ExecutorException { - try { - logger.warning(Logger.SECURITY, "Initiating executable: " + executable + " " + params + " in " + workdir); - - // command must exactly match the canonical path and must actually exist on the file system - // using equalsIgnoreCase for Windows, although this isn't quite as strong as it should be - if (!executable.getCanonicalPath().equalsIgnoreCase(executable.getPath())) { - throw new ExecutorException("Execution failure", "Invalid path to executable file: " + executable); - } - if (!executable.exists()) { - throw new ExecutorException("Execution failure", "No such executable: " + executable); - } - - // escape any special characters in the parameters - for ( int i = 0; i < params.size(); i++ ) { - String param = (String)params.get(i); - params.set( i, ESAPI.encoder().encodeForOS(codec, param)); - } - - // working directory must exist - if (!workdir.exists()) { - throw new ExecutorException("Execution failure", "No such working directory for running executable: " + workdir.getPath()); - } - - params.add(0, executable.getCanonicalPath()); - String[] command = (String[])params.toArray( new String[0] ); - Process process = Runtime.getRuntime().exec(command, new String[0], workdir); - - // Future - this is how to implement this in Java 1.5+ - // ProcessBuilder pb = new ProcessBuilder(params); - // Map env = pb.environment(); - // Security check - clear environment variables! - // env.clear(); - // pb.directory(workdir); - // pb.redirectErrorStream(true); - // Process process = pb.start(); - - String output = readStream( process.getInputStream() ); - String errors = readStream( process.getErrorStream() ); - if ( errors != null && errors.length() > 0 ) { - logger.warning( Logger.SECURITY, "Error during system command: " + errors ); - } - logger.warning(Logger.SECURITY, "System command complete: " + params); - return output; - } catch (Exception e) { - throw new ExecutorException("Execution failure", "Exception thrown during execution of system command: " + e.getMessage(), e); - } - } - - - private String readStream( InputStream is ) throws IOException { - InputStreamReader isr = new InputStreamReader(is); - BufferedReader br = new BufferedReader(isr); - StringBuffer sb = new StringBuffer(); - String line; - while ((line = br.readLine()) != null) { - sb.append(line + "\n"); - } - return sb.toString(); - } - -} diff --git a/src/org/owasp/esapi/reference/DefaultHTTPUtilities.java b/src/org/owasp/esapi/reference/DefaultHTTPUtilities.java deleted file mode 100644 index 5852122cb..000000000 --- a/src/org/owasp/esapi/reference/DefaultHTTPUtilities.java +++ /dev/null @@ -1,621 +0,0 @@ -/** - * 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.reference; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - -import javax.servlet.RequestDispatcher; -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 org.apache.commons.fileupload.FileItem; -import org.apache.commons.fileupload.ProgressListener; -import org.apache.commons.fileupload.disk.DiskFileItemFactory; -import org.apache.commons.fileupload.servlet.ServletFileUpload; -import org.owasp.esapi.ESAPI; -import org.owasp.esapi.Logger; -import org.owasp.esapi.User; -import org.owasp.esapi.errors.AccessControlException; -import org.owasp.esapi.errors.AuthenticationException; -import org.owasp.esapi.errors.EncodingException; -import org.owasp.esapi.errors.EncryptionException; -import org.owasp.esapi.errors.IntegrityException; -import org.owasp.esapi.errors.IntrusionException; -import org.owasp.esapi.errors.ValidationException; -import org.owasp.esapi.errors.ValidationUploadException; -import org.owasp.esapi.filters.SafeRequest; -import org.owasp.esapi.filters.SafeResponse; - -/** - * 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. - * - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security - * @since June 1, 2007 - * @see org.owasp.esapi.HTTPUtilities - */ -public class DefaultHTTPUtilities implements org.owasp.esapi.HTTPUtilities { - - /** The logger. */ - private final Logger logger = ESAPI.getLogger("HTTPUtilities"); - - /** The max bytes. */ - int maxBytes = ESAPI.securityConfiguration().getAllowedFileUploadSize(); - - /* - * The currentRequest ThreadLocal variable is used to make the currentRequest available to any call in any part of an - * application. This enables API's for actions that require the request to be much simpler. For example, the logout() - * method in the Authenticator class requires the currentRequest to get the session in order to invalidate it. - */ - private ThreadLocalRequest currentRequest = new ThreadLocalRequest(); - - /* - * The currentResponse ThreadLocal variable is used to make the currentResponse available to any call in any part of an - * application. This enables API's for actions that require the response to be much simpler. For example, the logout() - * method in the Authenticator class requires the currentResponse to kill the JSESSIONID cookie. - */ - private ThreadLocalResponse currentResponse = new ThreadLocalResponse(); - - - public DefaultHTTPUtilities() { - } - - /** - * @see org.owasp.esapi.HTTPUtilities#addCSRFToken(java.lang.String) - */ - public String addCSRFToken(String href) { - User user = ESAPI.authenticator().getCurrentUser(); - if (user.isAnonymous() || user == null) { - return href; - } - - if ( ( href.indexOf( '?') != -1 ) || ( href.indexOf( '&' ) != -1 ) ) { - return href + "&" + user.getCSRFToken(); - } else { - return href + "?" + user.getCSRFToken(); - } - } - - - /** - * Returns the first cookie matching the provided name. - */ - public Cookie getCookie(HttpServletRequest request, String name) { - Cookie[] cookies = request.getCookies(); - if (cookies != null) { - for (int i = 0; i < cookies.length; i++) { - Cookie cookie = cookies[i]; - if (cookie.getName().equals(name)) { - return cookie; - } - } - } - return null; - } - - /** - * @see org.owasp.esapi.HTTPUtilities#getCSRFToken() - */ - public String getCSRFToken() { - User user = ESAPI.authenticator().getCurrentUser(); - - if (user == null) return null; - return user.getCSRFToken(); - } - - /** - * 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. - */ - public String setRememberToken( HttpServletRequest request, HttpServletResponse response, String password, int maxAge, String domain, String path ) { - User user = ESAPI.authenticator().getCurrentUser(); - try { - killCookie(request, response, REMEMBER_TOKEN_COOKIE_NAME ); - String random = ESAPI.randomizer().getRandomString(8, DefaultEncoder.CHAR_ALPHANUMERICS); - String clearToken = random + ":" + user.getAccountName() + ":" + password; - long expiry = ESAPI.encryptor().getRelativeTimeStamp(maxAge * 1000); - String cryptToken = ESAPI.encryptor().seal(clearToken, expiry); - new SafeResponse(response).addCookie(REMEMBER_TOKEN_COOKIE_NAME, cryptToken, maxAge, domain, path ); - logger.info(Logger.SECURITY, "Enabled remember me token for " + user.getAccountName() ); - return cryptToken; - } catch( IntegrityException e ) { - logger.warning(Logger.SECURITY, "Attempt to set remember me token failed for " + user.getAccountName(), e ); - return null; - } - } - - /** - * 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. - */ - public void assertSecureRequest(HttpServletRequest request) throws AccessControlException { - if ( !isSecureChannel( request ) ) { - throw new AccessControlException( "Insecure request received", "Received non-SSL request" ); - } - String receivedMethod = request.getMethod(); - String requiredMethod = "POST"; - if ( !receivedMethod.equals( requiredMethod ) ) { - throw new AccessControlException( "Insecure request received", "Received request using " + receivedMethod + " when only " + requiredMethod + " is allowed" ); - } - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.HTTPUtilities#changeSessionIdentifier() - */ - public HttpSession changeSessionIdentifier(HttpServletRequest request) throws AuthenticationException { - - // get the current session - HttpSession session = request.getSession(); - - // make a copy of the session content - Map temp = new HashMap(); - Enumeration e = session.getAttributeNames(); - while (e != null && e.hasMoreElements()) { - String name = (String) e.nextElement(); - Object value = session.getAttribute(name); - temp.put(name, value); - } - - // kill the old session and create a new one - session.invalidate(); - HttpSession newSession = request.getSession(); - - // copy back the session content - Iterator i = temp.entrySet().iterator(); - while (i.hasNext()) { - Map.Entry entry = (Map.Entry) i.next(); - newSession.setAttribute((String) entry.getKey(), entry.getValue()); - } - return newSession; - } - - - - /* - * This implementation uses the parameter name to store the token. This makes the CSRF - * token a bit harder to search for in an XSS attack. - * (non-Javadoc) - * @see org.owasp.esapi.HTTPUtilities#verifyCSRFToken() - */ - public void verifyCSRFToken(HttpServletRequest request) throws IntrusionException { - User user = ESAPI.authenticator().getCurrentUser(); - - // check if user authenticated with this request - no CSRF protection required - if( request.getAttribute(user.getCSRFToken()) != null ) { - return; - } - if ( request.getParameter(user.getCSRFToken()) == null) { - throw new IntrusionException("Authentication failed", "Possibly forged HTTP request without proper CSRF token detected"); - } - } - - /* - * (non-Javadoc) - * @see org.owasp.esapi.HTTPUtilities#decryptHiddenField(java.lang.String) - */ - public String decryptHiddenField(String encrypted) { - try { - return ESAPI.encryptor().decrypt(encrypted); - } catch( EncryptionException e ) { - throw new IntrusionException("Invalid request","Tampering detected. Hidden field data did not decrypt properly.", e); - } - } - - - /* - * (non-Javadoc) - * @see org.owasp.esapi.HTTPUtilities#decryptQuueryString(java.lang.String) - */ - public Map decryptQueryString(String encrypted) throws EncryptionException { - String plaintext = ESAPI.encryptor().decrypt(encrypted); - return queryToMap(plaintext); - } - - /** - * @throws EncryptionException - * @see org.owasp.esapi.HTTPUtilities#decryptStateFromCookie() - */ - public Map decryptStateFromCookie(HttpServletRequest request) throws EncryptionException { - Cookie[] cookies = request.getCookies(); - Cookie c = null; - for ( int i = 0; i < cookies.length; i++ ) { - if ( cookies[i].getName().equals( "state" ) ) { - c = cookies[i]; - } - } - String encrypted = c.getValue(); - String plaintext = ESAPI.encryptor().decrypt(encrypted); - - return queryToMap( plaintext ); - } - - /* - * (non-Javadoc) - * @see org.owasp.esapi.HTTPUtilities#encryptHiddenField(java.lang.String) - */ - public String encryptHiddenField(String value) throws EncryptionException { - return ESAPI.encryptor().encrypt(value); - } - - /* - * (non-Javadoc) - * @see org.owasp.esapi.HTTPUtilities#encryptQueryString(java.lang.String) - */ - public String encryptQueryString(String query) throws EncryptionException { - return ESAPI.encryptor().encrypt( query ); - } - - /** - * @throws EncryptionException - * @see org.owasp.esapi.HTTPUtilities#encryptStateInCookie(java.util.Map) - */ - public void encryptStateInCookie(HttpServletResponse response, Map cleartext) throws EncryptionException { - StringBuffer sb = new StringBuffer(); - Iterator i = cleartext.entrySet().iterator(); - while ( i.hasNext() ) { - try { - Map.Entry entry = (Map.Entry)i.next(); - String name = ESAPI.encoder().encodeForURL( entry.getKey().toString() ); - String value = ESAPI.encoder().encodeForURL( entry.getValue().toString() ); - sb.append( name + "=" + value ); - if ( i.hasNext() ) sb.append( "&" ); - } catch( EncodingException e ) { - logger.error(Logger.SECURITY, "Problem encrypting state in cookie - skipping entry", e ); - } - } - String encrypted = ESAPI.encryptor().encrypt(sb.toString()); - new SafeResponse(response).addCookie("state", encrypted, -1, null, null ); - } - - /** - * 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. - * - * @see org.owasp.esapi.HTTPUtilities#safeGetFileUploads(java.io.File, java.io.File) - * @return list of File objects for new files in final directory - */ - public List getSafeFileUploads(HttpServletRequest request, File tempDir, File finalDir) throws ValidationException { - if ( !tempDir.exists() ) tempDir.mkdirs(); - if ( !finalDir.exists() ) finalDir.mkdirs(); - List newFiles = new ArrayList(); - try { - final HttpSession session = request.getSession(); - if (!ServletFileUpload.isMultipartContent(request)) { - throw new ValidationUploadException("Upload failed", "Not a multipart request"); - } - - // this factory will store ALL files in the temp directory, - // regardless of size - DiskFileItemFactory factory = new DiskFileItemFactory(0, tempDir); - ServletFileUpload upload = new ServletFileUpload(factory); - upload.setSizeMax(maxBytes); - - // Create a progress listener - ProgressListener progressListener = new ProgressListener() { - private long megaBytes = -1; - private long progress = 0; - - public void update(long pBytesRead, long pContentLength, int pItems) { - if (pItems == 0) - return; - long mBytes = pBytesRead / 1000000; - if (megaBytes == mBytes) - return; - megaBytes = mBytes; - progress = (long) (((double) pBytesRead / (double) pContentLength) * 100); - session.setAttribute("progress", Long.toString(progress)); - // logger.logSuccess(Logger.SECURITY, " Item " + pItems + " (" + progress + "% of " + pContentLength + " bytes]"); - } - }; - upload.setProgressListener(progressListener); - - List items = upload.parseRequest(request); - Iterator i = items.iterator(); - while (i.hasNext()) { - FileItem item = (FileItem) i.next(); - if (!item.isFormField() && item.getName() != null && !(item.getName().equals("")) ) { - String[] fparts = item.getName().split("[\\/\\\\]"); - String filename = fparts[fparts.length - 1]; - - if (!ESAPI.validator().isValidFileName("upload", filename, false)) { - throw new ValidationUploadException("Upload only simple filenames with the following extensions " + ESAPI.securityConfiguration().getAllowedFileExtensions(), "Upload failed isValidFileName check"); - } - - logger.info(Logger.SECURITY, "File upload requested: " + filename); - File f = new File(finalDir, filename); - if (f.exists()) { - String[] parts = filename.split("\\/."); - String extension = ""; - if (parts.length > 1) { - extension = parts[parts.length - 1]; - } - String filenm = filename.substring(0, filename.length() - extension.length()); - f = File.createTempFile(filenm, "." + extension, finalDir); - } - item.write(f); - newFiles.add( f ); - // delete temporary file - item.delete(); - logger.fatal(Logger.SECURITY, "File successfully uploaded: " + f); - session.setAttribute("progress", Long.toString(0)); - } - } - } catch (Exception e) { - if (e instanceof ValidationUploadException) { - throw (ValidationException)e; - } - throw new ValidationUploadException("Upload failure", "Problem during upload:" + e.getMessage(), e); - } - return newFiles; - } - - /** - * 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. - */ - public boolean isSecureChannel(HttpServletRequest request) { - if( ( request.getRequestURL() == null ) || ( request.getRequestURL().toString().length() == 0 )) - return false; - return (request.getRequestURL().charAt(4) == 's'); - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.HTTPUtilities#killAllCookies() - */ - public void killAllCookies(HttpServletRequest request, HttpServletResponse response) { - Cookie[] cookies = request.getCookies(); - if (cookies != null) { - for (int i = 0; i < cookies.length; i++) { - Cookie cookie = cookies[i]; - killCookie(request, response, cookie.getName()); - } - } - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.HTTPUtilities#killCookie(java.lang.String) - */ - public void killCookie(HttpServletRequest request, HttpServletResponse response, String name) { - String path = "//"; - String domain=""; - Cookie cookie = ESAPI.httpUtilities().getCookie(request, name); - if ( cookie != null ) { - path = cookie.getPath(); - domain = cookie.getDomain(); - } - SafeResponse safeResponse = new SafeResponse( response ); - safeResponse.addCookie(name, "deleted", 0, domain, path); - } - - private Map queryToMap(String query) { - TreeMap map = new TreeMap(); - String[] parts = query.split("&"); - for ( int j = 0; j < parts.length; j++ ) { - try { - String[] nvpair = parts[j].split("="); - String name = ESAPI.encoder().decodeFromURL(nvpair[0]); - String value = ESAPI.encoder().decodeFromURL(nvpair[1]); - map.put( name, value); - } catch( EncodingException e ) { - // skip the nvpair with the encoding problem - note this is already logged. - } - } - return map; - } - - /* - * This implementation simply checks to make sure that the forward location starts with "WEB-INF" and - * is intended for use in frameworks that forward to JSP files inside the WEB-INF folder. - * - * @see org.owasp.esapi.HTTPUtilities#safeSendForward(java.lang.String, java.lang.String) - */ - public void safeSendForward(HttpServletRequest request, HttpServletResponse response, String context, String location) throws AccessControlException,ServletException,IOException { - if (!location.startsWith("WEB-INF")) { - throw new AccessControlException("Forward failed", "Bad forward location: " + location); - } - RequestDispatcher dispatcher = request.getRequestDispatcher(location); - dispatcher.forward( request, response ); - } - - - /** - * 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. - * - * @see org.owasp.esapi.HTTPUtilities#safeSetContentType(java.lang.String) - */ - public void safeSetContentType(HttpServletResponse response) { - response.setContentType(((DefaultSecurityConfiguration)ESAPI.securityConfiguration()).getResponseContentType()); - } - - /** - * Set headers to protect sensitive information against being cached in the - * browser. - * - * @see org.owasp.esapi.HTTPUtilities#setNoCacheHeaders(javax.servlet.http.HttpServletResponse) - */ - public void setNoCacheHeaders(HttpServletResponse response) { - // HTTP 1.1 - response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate"); - - // HTTP 1.0 - response.setHeader("Pragma","no-cache"); - response.setDateHeader("Expires", -1); - } - - - /* (non-Javadoc) - * @see org.owasp.esapi.HTTPUtilities#getCurrentRequest() - */ - public SafeRequest getCurrentRequest() { - SafeRequest request = (SafeRequest)currentRequest.get(); - if ( request == null ) throw new NullPointerException( "Cannot use current request until it is set with HTTPUtilities.setCurrentHTTP()" ); - return request; - } - - /* (non-Javadoc) - * @see org.owasp.esapi.HTTPUtilities#getCurrentResponse() - */ - public SafeResponse getCurrentResponse() { - SafeResponse response = (SafeResponse)currentResponse.get(); - if ( response == null ) throw new NullPointerException( "Cannot use current response until it is set with HTTPUtilities.setCurrentHTTP()" ); - return response; - } - - /* (non-Javadoc) - * @see org.owasp.esapi.HTTPUtilities#setCurrentHTTP(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) - */ - public void setCurrentHTTP(HttpServletRequest request, HttpServletResponse response) { - SafeRequest safeRequest = null; - SafeResponse safeResponse = null; - - // wrap if necessary - if ( request instanceof SafeRequest ) { - safeRequest = (SafeRequest)request; - } else { - safeRequest = new SafeRequest( request ); - } - if ( response instanceof SafeResponse ) { - safeResponse = (SafeResponse)response; - } else { - safeResponse = new SafeResponse( response ); - } - - currentRequest.set(safeRequest); - currentResponse.set(safeResponse); - } - - public void logHTTPRequest(HttpServletRequest request, Logger logger) { - logHTTPRequest( request, logger, null ); - } - - /** - * 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. - * - * @see org.owasp.esapi.Logger#logHTTPRequest(org.owasp.esapi.Logger,java.util.List) - */ - public void logHTTPRequest(HttpServletRequest request, Logger logger, List parameterNamesToObfuscate) { - StringBuffer params = new StringBuffer(); - Iterator i = request.getParameterMap().keySet().iterator(); - while (i.hasNext()) { - String key = (String) i.next(); - String[] value = (String[]) request.getParameterMap().get(key); - for (int j = 0; j < value.length; j++) { - params.append(key + "="); - if (parameterNamesToObfuscate != null && parameterNamesToObfuscate.contains(key)) { - params.append("********"); - } else { - params.append(value[j]); - } - if (j < value.length - 1) { - params.append("&"); - } - } - if (i.hasNext()) - params.append("&"); - } - Cookie[] cookies = request.getCookies(); - if ( cookies != null ) { - for ( int c=0; c 0 ? "?" + params : ""); - logger.info(Logger.SECURITY, msg); - } - - /** - * Defines the ThreadLocalRequest to store the current request for this thread. - */ - private class ThreadLocalRequest extends InheritableThreadLocal { - - public Object initialValue() { - return null; - } - - public SafeRequest getRequest() { - return (SafeRequest)super.get(); - } - - public void setRequest(SafeRequest newRequest) { - super.set(newRequest); - } - }; - - /** - * Defines the ThreadLocalResponse to store the current response for this thread. - */ - private class ThreadLocalResponse extends InheritableThreadLocal { - - public Object initialValue() { - return null; - } - - public SafeResponse getResponse() { - return (SafeResponse)super.get(); - } - - public void setResponse(SafeResponse newResponse) { - super.set(newResponse); - } - }; - -} diff --git a/src/org/owasp/esapi/reference/DefaultIntrusionDetector.java b/src/org/owasp/esapi/reference/DefaultIntrusionDetector.java deleted file mode 100644 index 83e7d7d11..000000000 --- a/src/org/owasp/esapi/reference/DefaultIntrusionDetector.java +++ /dev/null @@ -1,183 +0,0 @@ -/** - * 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.reference; - -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Stack; -import java.util.WeakHashMap; - -import org.owasp.esapi.ESAPI; -import org.owasp.esapi.Logger; -import org.owasp.esapi.User; -import org.owasp.esapi.SecurityConfiguration.Threshold; -import org.owasp.esapi.errors.EnterpriseSecurityException; -import org.owasp.esapi.errors.IntrusionException; - -/** - * 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. - * - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security - * @since June 1, 2007 - * @see org.owasp.esapi.IntrusionDetector - */ -public class DefaultIntrusionDetector implements org.owasp.esapi.IntrusionDetector { - - /** The logger. */ - private final Logger logger = ESAPI.getLogger("IntrusionDetector"); - - private Map userEvents = new WeakHashMap(); - - public DefaultIntrusionDetector() { - } - - /** - * This implementation uses an exception store in each User object to track - * exceptions. - * - * @param e - * the e - * - * @throws IntrusionException - * the intrusion exception - * - * @see org.owasp.esapi.IntrusionDetector#addException(org.owasp.esapi.errors.EnterpriseSecurityException) - */ - public void addException(Exception e) { - if ( e instanceof EnterpriseSecurityException ) { - logger.warning( Logger.SECURITY, ((EnterpriseSecurityException)e).getLogMessage(), e ); - } else { - logger.warning( Logger.SECURITY, e.getMessage(), e ); - } - - // add the exception to the current user, which may trigger a detector - User user = ESAPI.authenticator().getCurrentUser(); - String eventName = e.getClass().getName(); - - if ( e instanceof IntrusionException) { - return; - } - - // add the exception to the user's store, handle IntrusionException if thrown - try { - addSecurityEvent(user, eventName); - } catch( IntrusionException ex ) { - Threshold quota = ESAPI.securityConfiguration().getQuota(eventName); - Iterator i = quota.actions.iterator(); - while ( i.hasNext() ) { - String action = (String)i.next(); - String message = "User exceeded quota of " + quota.count + " per "+ quota.interval +" seconds for event " + eventName + ". Taking actions " + quota.actions; - takeSecurityAction( action, message ); - } - } - } - - /** - * Adds the event to the IntrusionDetector. - * - * @param event the event - * @param logMessage the message to log - * @throws IntrusionException the intrusion exception - */ - public void addEvent(String eventName, String logMessage) throws IntrusionException { - logger.warning( Logger.SECURITY, "Security event " + eventName + " received : " + logMessage ); - - // add the event to the current user, which may trigger a detector - User user = ESAPI.authenticator().getCurrentUser(); - try { - addSecurityEvent(user, "event." + eventName); - } catch( IntrusionException ex ) { - Threshold quota = ESAPI.securityConfiguration().getQuota("event." + eventName); - Iterator i = quota.actions.iterator(); - while ( i.hasNext() ) { - String action = (String)i.next(); - String message = "User exceeded quota of " + quota.count + " per "+ quota.interval +" seconds for event " + eventName + ". Taking actions " + quota.actions; - takeSecurityAction( action, message ); - } - } - } - - - private void takeSecurityAction( String action, String message ) { - if ( action.equals( "log" ) ) { - logger.fatal( Logger.SECURITY, "INTRUSION - " + message ); - } - User user = ESAPI.authenticator().getCurrentUser(); - if (user == User.ANONYMOUS) - return; - if ( action.equals( "disable" ) ) { - user.disable(); - } - if ( action.equals( "logout" ) ) { - user.logout(); - } - } - - /** - * Adds a security event to the user. - * - * @param event the event - */ - private void addSecurityEvent(User user, String eventName) throws IntrusionException { - Map events = (Map) userEvents.get(user.getAccountName()); - if (events == null) { - events = new HashMap(); - userEvents.put(user.getAccountName(), events); - } - Event event = (Event)events.get( eventName ); - if ( event == null ) { - event = new Event( eventName ); - events.put( eventName, event ); - } - - Threshold q = ESAPI.securityConfiguration().getQuota( eventName ); - if ( q.count > 0 ) { - event.increment(q.count, q.interval); - } - } - - private static class Event { - public String key; - public Stack times = new Stack(); - public long count = 0; - public Event( String key ) { - this.key = key; - } - public void increment(int count, long interval) throws IntrusionException { - Date now = new Date(); - times.add( 0, now ); - while ( times.size() > count ) times.remove( times.size()-1 ); - if ( times.size() == count ) { - Date past = (Date)times.get( count-1 ); - long plong = past.getTime(); - long nlong = now.getTime(); - if ( nlong - plong < interval * 1000 ) { - throw new IntrusionException( "Threshold exceeded", "Exceeded threshold for " + key ); - } - } - } - } -} diff --git a/src/org/owasp/esapi/reference/DefaultRandomizer.java b/src/org/owasp/esapi/reference/DefaultRandomizer.java deleted file mode 100644 index 793406078..000000000 --- a/src/org/owasp/esapi/reference/DefaultRandomizer.java +++ /dev/null @@ -1,167 +0,0 @@ -/** - * 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.reference; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; - -import org.owasp.esapi.ESAPI; -import org.owasp.esapi.Logger; -import org.owasp.esapi.errors.EncryptionException; - -/** - * 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. - * - * @author Jeff Williams - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security - * @since June 1, 2007 - * @see org.owasp.esapi.Randomizer - */ -public class DefaultRandomizer implements org.owasp.esapi.Randomizer { - - /** The sr. */ - private SecureRandom secureRandom = null; - - /** The logger. */ - private final Logger logger = ESAPI.getLogger("Randomizer"); - - /** - * Hide the constructor for the Singleton pattern. - */ - public DefaultRandomizer() { - String algorithm = ESAPI.securityConfiguration().getRandomAlgorithm(); - try { - secureRandom = SecureRandom.getInstance(algorithm); - } catch (NoSuchAlgorithmException e) { - // Can't throw an exception from the constructor, but this will get - // it logged and tracked - new EncryptionException("Error creating randomizer", "Can't find random algorithm " + algorithm, e); - } - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IRandomizer#getRandomString(int, char[]) - */ - public String getRandomString(int length, char[] characterSet) { - StringBuffer sb = new StringBuffer(); - for (int loop = 0; loop < length; loop++) { - int index = secureRandom.nextInt(characterSet.length); - sb.append(characterSet[index]); - } - String nonce = sb.toString(); - return nonce; - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IRandomizer#getRandomBoolean() - */ - public boolean getRandomBoolean() { - return secureRandom.nextBoolean(); - } - - - /** - * (non-Javadoc) - * - * @see org.owasp.esapi.Randomizer#getRandomInteger(int, int) - */ - public int getRandomInteger(int min, int max) { - return secureRandom.nextInt(max - min) + min; - } - - - /** - * (non-Javadoc) - * - * @see org.owasp.esapi.Randomizer#getRandomLong() - */ - public long getRandomLong() { - return secureRandom.nextLong(); - } - - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IRandomizer#getRandomReal(float, float) - */ - public float getRandomReal(float min, float max) { - float factor = max - min; - return secureRandom.nextFloat() * factor + min; - } - - /** - * Returns an unguessable random filename with the specified extension. - */ - public String getRandomFilename(String extension) { - return this.getRandomString(12, DefaultEncoder.CHAR_ALPHANUMERICS) + "." + extension; - } - - public String getRandomGUID() throws EncryptionException { - // create random string to seed the GUID - StringBuffer sb = new StringBuffer(); - try { - sb.append(InetAddress.getLocalHost().toString()); - } catch (UnknownHostException e) { - sb.append("0.0.0.0"); - } - sb.append(":"); - sb.append(Long.toString(System.currentTimeMillis())); - sb.append(":"); - sb.append(this.getRandomString(20, DefaultEncoder.CHAR_ALPHANUMERICS)); - - // hash the random string to get some random bytes - String hash = ESAPI.encryptor().hash(sb.toString(), "salt"); - byte[] array = null; - try { - array = ESAPI.encoder().decodeFromBase64(hash); - } catch (IOException e) { - logger.fatal(Logger.SECURITY, "Problem decoding hash while creating GUID: " + hash); - } - - // convert to printable hexadecimal characters - StringBuffer hex = new StringBuffer(); - for (int j = 0; j < array.length; ++j) { - int b = array[j] & 0xFF; - if (b < 0x10) - hex.append('0'); - hex.append(Integer.toHexString(b)); - } - String raw = hex.toString().toUpperCase(); - - // convert to standard GUID format - StringBuffer result = new StringBuffer(); - result.append(raw.substring(0, 8)); - result.append("-"); - result.append(raw.substring(8, 12)); - result.append("-"); - result.append(raw.substring(12, 16)); - result.append("-"); - result.append(raw.substring(16, 20)); - result.append("-"); - result.append(raw.substring(20)); - return result.toString(); - } - -} diff --git a/src/org/owasp/esapi/reference/DefaultSecurityConfiguration.java b/src/org/owasp/esapi/reference/DefaultSecurityConfiguration.java deleted file mode 100644 index a695282a6..000000000 --- a/src/org/owasp/esapi/reference/DefaultSecurityConfiguration.java +++ /dev/null @@ -1,459 +0,0 @@ -/** - * 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.reference; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.TreeSet; -import java.util.logging.Level; -import java.util.regex.Pattern; - -import org.owasp.esapi.SecurityConfiguration; - -/** - * 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: - * - *

- * 
- * java -Dorg.owasp.esapi.resources="C:\temp\resources"
- * 
- * 
- * - * 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. - * - * @author jwilliams - */ - -public class DefaultSecurityConfiguration implements SecurityConfiguration { - - /** The properties. */ - private Properties properties = new Properties(); - - /** Regular expression cache */ - private Map regexMap = null; - - public static final String RESOURCE_DIRECTORY = "org.owasp.esapi.resources"; - - private static final String ALLOWED_LOGIN_ATTEMPTS = "AllowedLoginAttempts"; - - private static final String APPLICATION_NAME = "ApplicationName"; - - private static final String MASTER_PASSWORD = "MasterPassword"; - - private static final String MASTER_SALT = "MasterSalt"; - - private static final String VALID_EXTENSIONS = "ValidExtensions"; - - private static final String MAX_UPLOAD_FILE_BYTES = "MaxUploadFileBytes"; - - private static final String USERNAME_PARAMETER_NAME = "UsernameParameterName"; - - private static final String PASSWORD_PARAMETER_NAME = "PasswordParameterName"; - - private static final String MAX_OLD_PASSWORD_HASHES = "MaxOldPasswordHashes"; - - private static final String ENCRYPTION_ALGORITHM = "EncryptionAlgorithm"; - - private static final String HASH_ALGORITHM = "HashAlgorithm"; - - private static final String CHARACTER_ENCODING = "CharacterEncoding"; - - private static final String RANDOM_ALGORITHM = "RandomAlgorithm"; - - private static final String DIGITAL_SIGNATURE_ALGORITHM = "DigitalSignatureAlgorithm"; - - private static final String RESPONSE_CONTENT_TYPE = "ResponseContentType"; - - private static final String REMEMBER_TOKEN_DURATION = "RememberTokenDuration"; - - private static final String LOG_LEVEL = "LogLevel"; - - - protected final int MAX_REDIRECT_LOCATION = 1000; - - protected final int MAX_FILE_NAME_LENGTH = 1000; - - - /** - * Load properties from properties file. Set this with setResourceDirectory - * from your web application or ESAPI filter. For test and non-web applications, - * this implementation defaults to a System property defined when Java is launched. - * Use: - *

- * java -Dorg.owasp.esapi.resources="/path/resources" - *

- * where path references the appropriate directory in your system. - */ - private static String resourceDirectory = System.getProperty(RESOURCE_DIRECTORY); - - /** The last modified. */ - private static long lastModified = 0; - - /** - * Instantiates a new configuration. - */ - public DefaultSecurityConfiguration() { - loadConfiguration(); - } - - /* (non-Javadoc) - * @see org.owasp.esapi.interfaces.ISecurityConfiguration#getApplicationName() - */ - public String getApplicationName() { - return properties.getProperty(APPLICATION_NAME); - } - - /** - * Gets the master password. - * - * @return the master password - */ - public char[] getMasterPassword() { - return properties.getProperty(MASTER_PASSWORD).toCharArray(); - } - - /** - * Gets the keystore. - * - * @return the keystore - */ - public File getKeystore() { - return new File(getResourceDirectory(), "keystore"); - } - - /** - * Gets the resource directory. - * - * @return the resource directory - */ - public String getResourceDirectory() { - if ( resourceDirectory != null && !resourceDirectory.endsWith( System.getProperty("file.separator"))) { - resourceDirectory += System.getProperty("file.separator" ); - } - return resourceDirectory; - } - - - public void setResourceDirectory( String dir ) { - resourceDirectory = dir; - if ( resourceDirectory != null && !resourceDirectory.endsWith( System.getProperty("file.separator"))) { - resourceDirectory += System.getProperty("file.separator" ); - } - this.loadConfiguration(); - } - - /** - * Gets the master salt. - * - * @return the master salt - */ - public byte[] getMasterSalt() { - return properties.getProperty(MASTER_SALT).getBytes(); - } - - /** - * Gets the allowed file extensions. - * - * @return the allowed file extensions - */ - public List getAllowedFileExtensions() { - String def = ".zip,.pdf,.tar,.gz,.xls,.properties,.txt,.xml"; - String[] extList = properties.getProperty(VALID_EXTENSIONS,def).split(","); - return Arrays.asList(extList); - } - - /** - * Gets the allowed file upload size. - * - * @return the allowed file upload size - */ - public int getAllowedFileUploadSize() { - String bytes = properties.getProperty(MAX_UPLOAD_FILE_BYTES,"50000"); - return Integer.parseInt(bytes); - } - - /** - * Load ESAPI.properties from the classpath. For easy deployment, - * place your ESAPI.properties file in WEB-INF/classes - */ - private Properties loadConfigurationFromClasspath() - { - ClassLoader loader = getClass().getClassLoader(); - - Properties result = null; - - InputStream in = null; - try { - in = loader.getResourceAsStream("ESAPI.properties"); - if (in != null) { - result = new Properties (); - result.load(in); // Can throw IOException - } - } catch (Exception e) { - result = null; - - } finally { - if (in != null) try { in.close (); } catch (Throwable ignore) {} - } - - if (result == null) { - throw new IllegalArgumentException ("Can't load ESAPI.properties as a classloader resource"); - } - - return result; - } - - /** - * Load configuration. - */ - private void loadConfiguration() { - - File file = null; - - try { - properties = loadConfigurationFromClasspath(); - logSpecial("Loaded ESAPI properties from classpath", null); - - } catch (Exception ce) { - logSpecial("Can't load ESAPI properties from classpath, trying FileIO",ce); - file = new File(getResourceDirectory(), "ESAPI.properties"); - if (file.lastModified() == lastModified) - return; - - FileInputStream fis = null; - try { - fis = new FileInputStream( file ); - properties.load(fis); - logSpecial("Loaded ESAPI properties from " + file.getAbsolutePath(), null); - } catch (Exception e) { - logSpecial("Can't load ESAPI properties from " + file.getAbsolutePath(),e); - } finally { - try { - fis.close(); - } catch (IOException e) { - // give up - } - } - } - - logSpecial(" ========Master Configuration========", null); - Iterator i = new TreeSet( properties.keySet() ).iterator(); - while (i.hasNext()) { - String key = (String) i.next(); - logSpecial(" | " + key + "=" + properties.get(key),null); - } - - if (file != null) { - logSpecial(" ========Master Configuration========", null); - lastModified = file.lastModified(); - } - - // cache regular expressions - regexMap = new HashMap(); - - Iterator regexIterator = getValidationPatternNames(); - while ( regexIterator.hasNext() ) { - String name = (String)regexIterator.next(); - Pattern regex = getValidationPattern(name); - if ( name != null && regex != null ) { - regexMap.put( name, regex ); - } - } - - } - - private void logSpecial(String message, Throwable e) { - System.out.println(message); - } - - /** - * Gets the password parameter name. - * - * @return the password parameter name - */ - public String getPasswordParameterName() { - return properties.getProperty(PASSWORD_PARAMETER_NAME,"password"); - } - - /** - * Gets the username parameter name. - * - * @return the username parameter name - */ - public String getUsernameParameterName() { - return properties.getProperty(USERNAME_PARAMETER_NAME,"username"); - } - - /** - * Gets the encryption algorithm. - * - * @return the algorithm - */ - public String getEncryptionAlgorithm() { - return properties.getProperty(ENCRYPTION_ALGORITHM,"PBEWithMD5AndDES/CBC/PKCS5Padding"); - } - - /** - * Gets the hasing algorithm. - * - * @return the algorithm - */ - public String getHashAlgorithm() { - return properties.getProperty(HASH_ALGORITHM,"SHA-512"); - } - - /** - * Gets the character encoding. - * - * @return encoding name - */ - public String getCharacterEncoding() { - return properties.getProperty(CHARACTER_ENCODING,"UTF-8"); - } - - /** - * Gets the digital signature algorithm. - * - * @return encoding name - */ - public String getDigitalSignatureAlgorithm() { - return properties.getProperty(DIGITAL_SIGNATURE_ALGORITHM,"SHAwithDSA"); - } - - /** - * Gets the random number generation algorithm. - * - * @return encoding name - */ - public String getRandomAlgorithm() { - return properties.getProperty(RANDOM_ALGORITHM,"SHA1PRNG"); - } - - /** - * Gets the allowed login attempts. - * - * @return the allowed login attempts - */ - public int getAllowedLoginAttempts() { - String attempts = properties.getProperty(ALLOWED_LOGIN_ATTEMPTS,"5"); - return Integer.parseInt(attempts); - } - - /** - * Gets the max old password hashes. - * - * @return the max old password hashes - */ - public int getMaxOldPasswordHashes() { - String max = properties.getProperty(MAX_OLD_PASSWORD_HASHES,"12"); - return Integer.parseInt(max); - } - - - public Threshold getQuota(String eventName) { - int count = 0; - String countString = properties.getProperty(eventName + ".count"); - if (countString != null) { - count = Integer.parseInt(countString); - } - - int interval = 0; - String intervalString = properties.getProperty(eventName + ".interval"); - if (intervalString != null) { - interval = Integer.parseInt(intervalString); - } - - List actions = new ArrayList(); - String actionString = properties.getProperty(eventName + ".actions"); - if (actionString != null) { - String[] actionList = actionString.split(","); - actions = Arrays.asList(actionList); - } - - Threshold q = new Threshold(eventName, count, interval, actions); - return q; - } - - public Level getLogLevel() { - String level = properties.getProperty(LOG_LEVEL); - if (level.equalsIgnoreCase("TRACE")) - return Level.FINER; - if (level.equalsIgnoreCase("ERROR")) - return Level.WARNING; - if (level.equalsIgnoreCase("SEVERE")) - return Level.SEVERE; - if (level.equalsIgnoreCase("WARNING")) - return Level.WARNING; - if (level.equalsIgnoreCase("SUCCESS")) - return Level.INFO; - if (level.equalsIgnoreCase("DEBUG")) - return Level.CONFIG; - if (level.equalsIgnoreCase("NONE")) - return Level.OFF; - return Level.ALL; - } - - public String getResponseContentType() { - String def = "text/html; charset=UTF-8"; - return properties.getProperty( RESPONSE_CONTENT_TYPE, def ); - } - - public long getRememberTokenDuration() { - String value = properties.getProperty( REMEMBER_TOKEN_DURATION, "14" ); - long days = Long.parseLong( value ); - long duration = 1000 * 60 * 60 * 24 * days; - return duration; - } - - public Iterator getValidationPatternNames() { - TreeSet list = new TreeSet(); - Iterator i = properties.keySet().iterator(); - while( i.hasNext() ) { - String name = (String)i.next(); - if ( name.startsWith( "Validator.")) { - list.add( name.substring(name.indexOf('.') + 1 ) ); - } - } - return list.iterator(); - } - - public Pattern getValidationPattern( String key ) { - String value = properties.getProperty( "Validator." + key ); - if ( value == null ) return null; - Pattern pattern = Pattern.compile(value); - return pattern; - } - - public boolean getLogEncodingRequired() { - String value = properties.getProperty( "LogEncodingRequired" ); - if ( value != null && value.equalsIgnoreCase("true")) return true; - return false; - } -} diff --git a/src/org/owasp/esapi/reference/DefaultUser.java b/src/org/owasp/esapi/reference/DefaultUser.java deleted file mode 100644 index a1cd6a289..000000000 --- a/src/org/owasp/esapi/reference/DefaultUser.java +++ /dev/null @@ -1,607 +0,0 @@ -/** - * 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.reference; - -import java.io.Serializable; -import java.util.Collections; -import java.util.Date; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; - -import javax.servlet.http.HttpSession; - -import org.owasp.esapi.ESAPI; -import org.owasp.esapi.HTTPUtilities; -import org.owasp.esapi.Logger; -import org.owasp.esapi.User; -import org.owasp.esapi.errors.AuthenticationAccountsException; -import org.owasp.esapi.errors.AuthenticationException; -import org.owasp.esapi.errors.AuthenticationHostException; -import org.owasp.esapi.errors.AuthenticationLoginException; -import org.owasp.esapi.errors.EncryptionException; - -/** - * Reference implementation of the User interface. This implementation is serialized into a flat file in a simple format. - * - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security - * @since June 1, 2007 - * @see org.owasp.esapi.User - */ -public class DefaultUser implements User, Serializable { - - - /** The Constant serialVersionUID. */ - private static final long serialVersionUID = 1L; - - /** The logger. */ - private final Logger logger = ESAPI.getLogger("User"); - - /** The account id. */ - long accountId = 0; - - /** The account name. */ - private String accountName = ""; - - /** The screen name. */ - private String screenName = ""; - - /** The csrf token. */ - private String csrfToken = ""; - - /** The roles. */ - private Set roles = new HashSet(); - - /** The locked. */ - private boolean locked = false; - - /** The logged in. */ - private boolean loggedIn = true; - - /** The enabled. */ - private boolean enabled = false; - - /** The last host address used. */ - private String lastHostAddress; - - /** The last password change time. */ - private Date lastPasswordChangeTime = new Date(0); - - /** The last login time. */ - private Date lastLoginTime = new Date(0); - - /** The last failed login time. */ - private Date lastFailedLoginTime = new Date(0); - - /** The expiration time. */ - private Date expirationTime = new Date(Long.MAX_VALUE); - - /** A flag to indicate that the password must be changed before the account can be used. */ - // private boolean requiresPasswordChange = true; - - /** The failed login count. */ - private int failedLoginCount = 0; - - private final int MAX_ROLE_LENGTH = 250; - - /** - * Instantiates a new user. - */ - DefaultUser(String accountName) { - setAccountName(accountName); - while( true ) { - long id = Math.abs( ESAPI.randomizer().getRandomLong() ); - if ( ESAPI.authenticator().getUser( id ) == null && id != 0 ) { - setAccountId(id); - break; - } - } - } - - /* (non-Javadoc) - * @see org.owasp.esapi.interfaces.IUser#addRole(java.lang.String) - */ - public void addRole(String role) throws AuthenticationException { - String roleName = role.toLowerCase(); - if ( ESAPI.validator().isValidInput("addRole", roleName, "RoleName", MAX_ROLE_LENGTH, false) ) { - roles.add(roleName); - logger.info(Logger.SECURITY, "Role " + roleName + " added to " + getAccountName() ); - } else { - throw new AuthenticationAccountsException( "Add role failed", "Attempt to add invalid role " + roleName + " to " + getAccountName() ); - } - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IUser#addRoles(java.util.Set) - */ - public void addRoles(Set newRoles) throws AuthenticationException { - Iterator i = newRoles.iterator(); - while(i.hasNext()) { - addRole((String)i.next()); - } - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IUser#setPassword(java.lang.String, java.lang.String) - */ - public void changePassword(String oldPassword, String newPassword1, String newPassword2) throws AuthenticationException, EncryptionException { - ESAPI.authenticator().changePassword(this, oldPassword, newPassword1, newPassword2); - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IUser#disable() - */ - public void disable() { - enabled = false; - logger.info( Logger.SECURITY, "Account disabled: " + getAccountName() ); - } - - /** - * Enable the account - * - * @see org.owasp.esapi.User#enable() - */ - public void enable() { - this.enabled = true; - logger.info( Logger.SECURITY, "Account enabled: " + getAccountName() ); - } - - /* (non-Javadoc) - * @see org.owasp.esapi.User#getAccountId() - */ - public long getAccountId() { - return accountId; - } - - /** - * Gets the account name. - * - * @return the accountName - */ - public String getAccountName() { - return accountName; - } - - /** - * Gets the CSRF token. Use the HTTPUtilities.checkCSRFToken( request ) to verify the token. - * - * @return the csrfToken - */ - public String getCSRFToken() { - return csrfToken; - } - - /** - * Gets the expiration time. - * - * @return The expiration time of the current user. - */ - public Date getExpirationTime() { - return (Date)expirationTime.clone(); - } - - /** - * Gets the failed login count. - * - * @return the failedLoginCount - */ - public int getFailedLoginCount() { - return failedLoginCount; - } - - void setFailedLoginCount(int count) { - failedLoginCount = count; - } - - /** - * Gets the last failed login time. - * - * @return the lastFailedLoginTime - */ - public Date getLastFailedLoginTime() { - return (Date)lastFailedLoginTime.clone(); - } - - public String getLastHostAddress() { - if ( lastHostAddress == null ) { - return "local"; - } - return lastHostAddress; - } - - /** - * Gets the last login time. - * - * @return the lastLoginTime - */ - public Date getLastLoginTime() { - return (Date)lastLoginTime.clone(); - } - - /** - * Gets the last password change time. - * - * @return the lastPasswordChangeTime - */ - public Date getLastPasswordChangeTime() { - return (Date)lastPasswordChangeTime.clone(); - } - - public String getName() { - return this.getAccountName(); - } - - /** - * Gets the roles. - * - * @return the roles - */ - public Set getRoles() { - return Collections.unmodifiableSet(roles); - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IUser#getScreenName() - */ - public String getScreenName() { - return screenName; - } - - /* (non-Javadoc) - * @see org.owasp.esapi.interfaces.IUser#incrementFailedLoginCount() - */ - public void incrementFailedLoginCount() { - failedLoginCount++; - } - - /* (non-Javadoc) - * @see org.owasp.esapi.interfaces.IUser#isAnonymous() - */ - public boolean isAnonymous() { - // User cannot be anonymous, since we have a special IUser.ANONYMOUS instance - // for the anonymous user - return false; - } - - /** - * Checks if is enabled. - * - * @return the enabled - */ - public boolean isEnabled() { - return enabled; - } - - /* (non-Javadoc) - * @see org.owasp.esapi.interfaces.IUser#isExpired() - */ - public boolean isExpired() { - return getExpirationTime().before( new Date() ); - - // If expiration should happen automatically or based on lastPasswordChangeTime? - // long from = lastPasswordChangeTime.getTime(); - // long to = new Date().getTime(); - // double difference = to - from; - // long days = Math.round((difference / (1000 * 60 * 60 * 24))); - // return days > 60; - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IUser#isInRole(java.lang.String) - */ - public boolean isInRole(String role) { - return roles.contains(role.toLowerCase()); - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IUser#isLocked() - */ - public boolean isLocked() { - return locked; - } - - /* (non-Javadoc) - * @see org.owasp.esapi.interfaces.IUser#isLoggedIn() - */ - public boolean isLoggedIn() { - return loggedIn; - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IIntrusionDetector#isSessionAbsoluteTimeout(java.lang.String) - */ - public boolean isSessionAbsoluteTimeout() { - HttpSession session = ESAPI.httpUtilities().getCurrentRequest().getSession(); - Date deadline = new Date( session.getCreationTime() + 1000 * 60 * 60 * 2); - Date now = new Date(); - return now.after(deadline); - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IIntrusionDetector#isSessionTimeout(java.lang.String) - */ - public boolean isSessionTimeout() { - HttpSession session = ESAPI.httpUtilities().getCurrentRequest().getSession(); - Date deadline = new Date(session.getLastAccessedTime() + 1000 * 60 * 20); - Date now = new Date(); - return now.after(deadline); - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IUser#lock() - */ - public void lock() { - this.locked = true; - logger.info(Logger.SECURITY, "Account locked: " + getAccountName() ); - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IUser#login(java.lang.String) - */ - public void loginWithPassword(String password) throws AuthenticationException { - if ( password == null || password.equals("") ) { - setLastFailedLoginTime(new Date()); - incrementFailedLoginCount(); - throw new AuthenticationLoginException( "Login failed", "Missing password: " + accountName ); - } - - // don't let disabled users log in - if ( !isEnabled() ) { - setLastFailedLoginTime(new Date()); - incrementFailedLoginCount(); - throw new AuthenticationLoginException("Login failed", "Disabled user attempt to login: " + accountName ); - } - - // don't let locked users log in - if ( isLocked() ) { - setLastFailedLoginTime(new Date()); - incrementFailedLoginCount(); - throw new AuthenticationLoginException("Login failed", "Locked user attempt to login: " + accountName ); - } - - // don't let expired users log in - if ( isExpired() ) { - setLastFailedLoginTime(new Date()); - incrementFailedLoginCount(); - throw new AuthenticationLoginException("Login failed", "Expired user attempt to login: " + accountName ); - } - - logout(); - - if ( verifyPassword( password ) ) { - loggedIn = true; - ESAPI.httpUtilities().changeSessionIdentifier( ESAPI.currentRequest() ); - ESAPI.authenticator().setCurrentUser(this); - setLastLoginTime(new Date()); - setLastHostAddress( ESAPI.httpUtilities().getCurrentRequest().getRemoteHost() ); - logger.trace(Logger.SECURITY, "User logged in: " + accountName ); - } else { - loggedIn = false; - setLastFailedLoginTime(new Date()); - incrementFailedLoginCount(); - if (getFailedLoginCount() >= ESAPI.securityConfiguration().getAllowedLoginAttempts()) { - lock(); - } - throw new AuthenticationLoginException("Login failed", "Incorrect password provided for " + getAccountName() ); - } - } - - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IUser#logout() - */ - public void logout() { - ESAPI.httpUtilities().killCookie( ESAPI.currentRequest(), ESAPI.currentResponse(), HTTPUtilities.REMEMBER_TOKEN_COOKIE_NAME ); - - HttpSession session = ESAPI.currentRequest().getSession(false); - if (session != null) { - session.invalidate(); - } - ESAPI.httpUtilities().killCookie(ESAPI.currentRequest(), ESAPI.currentResponse(), "JSESSIONID"); - loggedIn = false; - logger.info(Logger.SECURITY, "Logout successful" ); - ESAPI.authenticator().setCurrentUser(User.ANONYMOUS); - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IUser#removeRole(java.lang.String) - */ - public void removeRole(String role) { - roles.remove(role.toLowerCase()); - logger.trace(Logger.SECURITY, "Role " + role + " removed from " + getAccountName() ); - } - - /** - * 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. - * - * @return the string - * - * @see org.owasp.esapi.User#resetCSRFToken() - */ - public String resetCSRFToken() { - // user.csrfToken = ESAPI.encryptor().hash( session.getId(),user.name ); - // user.csrfToken = ESAPI.encryptor().encrypt( address + ":" + ESAPI.encryptor().getTimeStamp(); - csrfToken = ESAPI.randomizer().getRandomString(8, DefaultEncoder.CHAR_ALPHANUMERICS); - return csrfToken; - } - - /** - * Sets the account id. - */ - private void setAccountId(long accountId) { - this.accountId = accountId; - } - - - /** - * Sets the account name. - * - * @param accountName - * the accountName to set - */ - public void setAccountName(String accountName) { - String old = getAccountName(); - this.accountName = accountName.toLowerCase(); - if (old != null) - logger.info(Logger.SECURITY, "Account name changed from " + old + " to " + getAccountName() ); - } - - /** - * Sets the expiration time. - * - * @param expirationTime - * the expirationTime to set - */ - public void setExpirationTime(Date expirationTime) { - this.expirationTime = new Date( expirationTime.getTime() ); - logger.info(Logger.SECURITY, "Account expiration time set to " + expirationTime + " for " + getAccountName() ); - } - - /** - * Sets the last failed login time. - * - * @param lastFailedLoginTime - * the lastFailedLoginTime to set - */ - public void setLastFailedLoginTime(Date lastFailedLoginTime) { - this.lastFailedLoginTime = lastFailedLoginTime; - logger.info(Logger.SECURITY, "Set last failed login time to " + lastFailedLoginTime + " for " + getAccountName() ); - } - - - /** - * Sets the last remote host address used by this User. - * @param remoteHost - */ - public void setLastHostAddress(String remoteHost) { - if ( lastHostAddress != null && !lastHostAddress.equals(remoteHost)) { - // returning remote address not remote hostname to prevent DNS lookup - new AuthenticationHostException("Host change", "User session just jumped from " + lastHostAddress + " to " + remoteHost ); - } - lastHostAddress = remoteHost; - } - - /** - * Sets the last login time. - * - * @param lastLoginTime - * the lastLoginTime to set - */ - public void setLastLoginTime(Date lastLoginTime) { - this.lastLoginTime = lastLoginTime; - logger.info(Logger.SECURITY, "Set last successful login time to " + lastLoginTime + " for " + getAccountName() ); - } - - /** - * Sets the last password change time. - * - * @param lastPasswordChangeTime - * the lastPasswordChangeTime to set - */ - public void setLastPasswordChangeTime(Date lastPasswordChangeTime) { - this.lastPasswordChangeTime = lastPasswordChangeTime; - logger.info(Logger.SECURITY, "Set last password change time to " + lastPasswordChangeTime + " for " + getAccountName() ); - } - - /** - * Sets the roles. - * - * @param roles - * the roles to set - */ - public void setRoles(Set roles) throws AuthenticationException { - this.roles = new HashSet(); - addRoles(roles); - logger.info(Logger.SECURITY, "Adding roles " + roles + " to " + getAccountName() ); - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IUser#setScreenName(java.lang.String) - */ - public void setScreenName(String screenName) { - this.screenName = screenName; - logger.info(Logger.SECURITY, "ScreenName changed to " + screenName + " for " + getAccountName() ); - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - public String toString() { - return "USER:" + accountName; - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IUser#unlock() - */ - public void unlock() { - this.locked = false; - this.failedLoginCount = 0; - logger.info( Logger.SECURITY, "Account unlocked: " + getAccountName() ); - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IUser#verifyPassword(java.lang.String) - */ - public boolean verifyPassword(String password) { - return ESAPI.authenticator().verifyPassword(this, password); - } - - /** - * Override clone and make final to prevent duplicate user objects. - */ - public final Object clone() throws java.lang.CloneNotSupportedException { - throw new java.lang.CloneNotSupportedException(); - } - -} diff --git a/src/org/owasp/esapi/reference/DefaultValidator.java b/src/org/owasp/esapi/reference/DefaultValidator.java deleted file mode 100644 index c579f02c8..000000000 --- a/src/org/owasp/esapi/reference/DefaultValidator.java +++ /dev/null @@ -1,1145 +0,0 @@ -/** - * 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 - * @author Jim Manico Aspect Security - * - * @created 2007 - */ -package org.owasp.esapi.reference; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.text.DateFormat; -import java.util.Arrays; -import java.util.Date; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; - -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; - -import org.owasp.esapi.ESAPI; -import org.owasp.esapi.ValidationErrorList; -import org.owasp.esapi.errors.EncodingException; -import org.owasp.esapi.errors.IntrusionException; -import org.owasp.esapi.errors.ValidationAvailabilityException; -import org.owasp.esapi.errors.ValidationException; -import org.owasp.validator.html.AntiSamy; -import org.owasp.validator.html.CleanResults; -import org.owasp.validator.html.Policy; -import org.owasp.validator.html.PolicyException; -import org.owasp.validator.html.ScanException; - -/** - * 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

&lt;
or - *
%26lt;
 or even 
%25%26lt;
are disallowed. - * - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security - * @author Jim Manico (jim.manico .at. aspectsecurity.com) Aspect Security - * - * @since June 1, 2007 - * @see org.owasp.esapi.Validator - */ -public class DefaultValidator implements org.owasp.esapi.Validator { - - /** OWASP AntiSamy markup verification policy */ - private Policy antiSamyPolicy = null; - - /** constants */ - private static final int MAX_CREDIT_CARD_LENGTH = 19; - private static final int MAX_PARAMETER_NAME_LENGTH = 100; - private static final int MAX_PARAMETER_VALUE_LENGTH = 65535; - - public DefaultValidator() { - } - - /** - * Returns true if data received from browser is valid. Only URL encoding is - * supported. Double encoding is treated as an attack. - * - * @param context A descriptive name for the field to validate. This is used for error facing validation messages and element identification. - * @param input The actual user input data to validate. - * @param type The regular expression name while maps to the actual regular expression from "ESAPI.properties". - * @param maxLength The maximum post-canonicalized String length allowed. - * @param 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. - * @return The canonicalized user input. - * @throws IntrusionException - */ - public boolean isValidInput(String context, String input, String type, int maxLength, boolean allowNull) throws IntrusionException { - try { - getValidInput( context, input, type, maxLength, allowNull); - return true; - } catch( Exception e ) { - return false; - } - } - - /** - * Validates data received from the browser and returns a safe version. Only - * URL encoding is supported. Double encoding is treated as an attack. - * - * @param context A descriptive name for the field to validate. This is used for error facing validation messages and element identification. - * @param input The actual user input data to validate. - * @param type The regular expression name while maps to the actual regular expression from "ESAPI.properties". - * @param maxLength The maximum post-canonicalized String length allowed. - * @param 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. - * @return The canonicalized user input. - * @throws ValidationException - * @throws IntrusionException - */ - public String getValidInput(String context, String input, String type, int maxLength, boolean allowNull) throws ValidationException, IntrusionException { - - try { - context = ESAPI.encoder().canonicalize( context ); - String canonical = ESAPI.encoder().canonicalize( input ); - - if ( type == null || type.length() == 0 ) { - throw new RuntimeException( "Validation misconfiguration, specified type to validate against was null: context=" + context + ", type=" + type + "), input=" + input ); - } - - if (isEmpty(canonical)) { - if (allowNull) return null; - throw new ValidationException( context + ": Input required.", "Input required: context=" + context + ", type=" + type + "), input=" + input, context ); - } - - if (canonical.length() > maxLength) { - throw new ValidationException( context + ": Invalid input. The maximum length of " + maxLength + " characters was exceeded.", "Input exceeds maximum allowed length of " + maxLength + " by " + (canonical.length()-maxLength) + " characters: context=" + context + ", type=" + type + "), input=" + input, context ); - } - - Pattern p = ((DefaultSecurityConfiguration)ESAPI.securityConfiguration()).getValidationPattern( type ); - if ( p == null ) { - try { - p = Pattern.compile( type ); - } catch( PatternSyntaxException e ) { - throw new RuntimeException( "Validation misconfiguration, specified type to validate against was null: context=" + context + ", type=" + type + "), input=" + input ); - } - } - - if ( !p.matcher(canonical).matches() ) { - throw new ValidationException( context + ": Invalid input. Please conform to: " + p.pattern() + " with a maximum length of " + maxLength, "Invalid input: context=" + context + ", type=" + type + "( " + p.pattern() + "), input=" + input, context ); - } - - return canonical; - - } catch (EncodingException e) { - throw new ValidationException( context + ": Invalid input. An encoding error occurred.", "Error canonicalizing user input", e, context); - } - } - - /** - * Validates data received from the browser and returns a safe version. Only - * URL encoding is supported. Double encoding is treated as an attack. - * - * @param context A descriptive name for the field to validate. This is used for error facing validation messages and element identification. - * @param input The actual user input data to validate. - * @param type The regular expression name while maps to the actual regular expression from "ESAPI.properties". - * @param maxLength The maximum post-canonicalized String length allowed. - * @param 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. - * @param errors If ValidationException is thrown, then add to error list instead of throwing out to caller - * @return The canonicalized user input. - * @throws IntrusionException - */ - public String getValidInput(String context, String input, String type, int maxLength, boolean allowNull, ValidationErrorList errors) throws IntrusionException { - - try { - return getValidInput(context, input, type, maxLength, allowNull); - } catch (ValidationException e) { - errors.addError(context, e); - } - return input; - } - - /** - * Returns true if input is a valid date according to the specified date format. - */ - public boolean isValidDate(String context, String input, DateFormat format, boolean allowNull) throws IntrusionException { - try { - getValidDate( context, input, format, allowNull); - return true; - } catch( Exception e ) { - return false; - } - } - - /* - * 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. - * - * @see org.owasp.esapi.interfaces.IValidator#getValidDate(java.lang.String) - */ - public Date getValidDate(String context, String input, DateFormat format, boolean allowNull) throws ValidationException, IntrusionException { - try { - if (isEmpty(input)) { - if (allowNull) return null; - throw new ValidationException( context + ": Input date required", "Input date required: context=" + context + ", input=" + input, context ); - } - - Date date = format.parse(input); - return date; - } catch (Exception e) { - throw new ValidationException( context + ": Invalid date must follow " + format + " format", "Invalid date: context=" + context + ", format=" + format + ", input=" + input, e, context); - } - } - - /* - * 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. - * - * @see org.owasp.esapi.interfaces.IValidator#getValidDate(java.lang.String) - */ - public Date getValidDate(String context, String input, DateFormat format, boolean allowNull, ValidationErrorList errors) throws IntrusionException { - - try { - return getValidDate(context, input, format, allowNull); - } catch (ValidationException e) { - errors.addError(context, e); - } - return null; - } - - /* - * 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. - * - * @see org.owasp.esapi.interfaces.IValidator#isValidSafeHTML(java.lang.String) - */ - public boolean isValidSafeHTML(String context, String input, int maxLength, boolean allowNull) throws IntrusionException { - - try { - if ( antiSamyPolicy == null ) { - if (ESAPI.securityConfiguration().getResourceDirectory() == null) { - - //load via classpath - ClassLoader loader = getClass().getClassLoader(); - - InputStream in = null; - try { - in = loader.getResourceAsStream("antisamy-esapi.xml"); - if (in != null) { - antiSamyPolicy = Policy.getInstance(in); - } - } catch (Exception e) { - antiSamyPolicy = null; - - } finally { - if (in != null) try { in.close (); } catch (Throwable ignore) {} - } - - if (antiSamyPolicy == null) { - throw new IllegalArgumentException ("Can't load antisamy-esapi.xml as a classloader resource"); - } - - } else { - //load via fileio - antiSamyPolicy = Policy.getInstance( ESAPI.securityConfiguration().getResourceDirectory() + "antisamy-esapi.xml"); - } - } - AntiSamy as = new AntiSamy(); - CleanResults test = as.scan(input, antiSamyPolicy); - return(test.getErrorMessages().size() == 0); - } catch (Exception e) { - return false; - } - } - - /* - * 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. - * - * @see org.owasp.esapi.interfaces.IValidator#getValidSafeHTML(java.lang.String) - */ - public String getValidSafeHTML( String context, String input, int maxLength, boolean allowNull ) throws ValidationException, IntrusionException { - - if (isEmpty(input)) { - if (allowNull) return null; - throw new ValidationException( context + ": Input HTML required", "Input HTML required: context=" + context + ", input=" + input, context ); - } - - if (input.length() > maxLength) { - throw new ValidationException( context + ": Invalid HTML input can not exceed " + maxLength + " characters", context + " input exceedes maxLength by " + (input.length()-maxLength) + " characters", context); - } - - try { - if ( antiSamyPolicy == null ) { - if (ESAPI.securityConfiguration().getResourceDirectory() == null) { - - //load via classpath - ClassLoader loader = getClass().getClassLoader(); - - InputStream in = null; - try { - in = loader.getResourceAsStream("antisamy-esapi.xml"); - if (in != null) { - antiSamyPolicy = Policy.getInstance(in); - } - } catch (Exception e) { - antiSamyPolicy = null; - - } finally { - if (in != null) try { in.close (); } catch (Throwable ignore) {} - } - - if (antiSamyPolicy == null) { - throw new IllegalArgumentException ("Can't load antisamy-esapi.xml as a classloader resource"); - } - - } else { - //load via fileio - antiSamyPolicy = Policy.getInstance( ESAPI.securityConfiguration().getResourceDirectory() + "antisamy-esapi.xml"); - } - } - AntiSamy as = new AntiSamy(); - CleanResults test = as.scan(input, antiSamyPolicy); - List errors = test.getErrorMessages(); - - if ( errors.size() > 0 ) { - // just create new exception to get it logged and intrusion detected - new ValidationException( "Invalid HTML input: context=" + context, "Invalid HTML input: context=" + context + ", errors=" + errors, context ); - } - - return(test.getCleanHTML().trim()); - - } catch (ScanException e) { - throw new ValidationException( context + ": Invalid HTML input", "Invalid HTML input: context=" + context + " error=" + e.getMessage(), e, context ); - - } catch (PolicyException e) { - throw new ValidationException( context + ": Invalid HTML input", "Invalid HTML input does not follow rules in antisamy-esapi.xml: context=" + context + " error=" + e.getMessage(), e, context ); - } - } - - /** - * ValidationErrorList variant of getValidSafeHTML - */ - public String getValidSafeHTML(String context, String input, int maxLength, boolean allowNull, ValidationErrorList errors) throws IntrusionException { - - try { - return getValidSafeHTML(context, input, maxLength, allowNull); - } catch (ValidationException e) { - errors.addError(context, e); - } - return input; - } - - /* - * Returns true if input is a valid credit card. Maxlength is mandated by valid credit card type. - * - * @see org.owasp.esapi.interfaces.IValidator#isValidCreditCard(java.lang.String) - */ - public boolean isValidCreditCard(String context, String input, boolean allowNull) throws IntrusionException { - try { - getValidCreditCard( context, input, allowNull); - return true; - } catch( Exception e ) { - return false; - } - } - - /** - * 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. - */ - public String getValidCreditCard(String context, String input, boolean allowNull) throws ValidationException, IntrusionException { - if (isEmpty(input)) { - if (allowNull) return null; - throw new ValidationException( context + ": Input credit card required", "Input credit card required: context=" + context + ", input=" + input, context ); - } - - String canonical = getValidInput( context, input, "CreditCard", MAX_CREDIT_CARD_LENGTH, allowNull); - - // perform Luhn algorithm checking - StringBuffer digitsOnly = new StringBuffer(); - char c; - for (int i = 0; i < canonical.length(); i++) { - c = canonical.charAt(i); - if (Character.isDigit(c)) { - digitsOnly.append(c); - } - } - - int sum = 0; - int digit = 0; - int addend = 0; - boolean timesTwo = false; - - for (int i = digitsOnly.length() - 1; i >= 0; i--) { - digit = Integer.parseInt(digitsOnly.substring(i, i + 1)); - if (timesTwo) { - addend = digit * 2; - if (addend > 9) { - addend -= 9; - } - } else { - addend = digit; - } - sum += addend; - timesTwo = !timesTwo; - } - - int modulus = sum % 10; - if (modulus != 0) throw new ValidationException( context + ": Invalid credit card input", "Invalid credit card input: context=" + context, context ); - - return canonical; - - } - - /** - * ValidationErrorList variant of getValidCreditCard - */ - public String getValidCreditCard(String context, String input, boolean allowNull, ValidationErrorList errors) throws IntrusionException { - - try { - return getValidCreditCard(context, input, allowNull); - } catch (ValidationException e) { - errors.addError(context, e); - } - return input; - } - - /** - * Returns true if the directory path (not including a filename) is valid. - * - * @see org.owasp.esapi.Validator#isValidDirectoryPath(java.lang.String) - */ - public boolean isValidDirectoryPath(String context, String input, boolean allowNull) throws IntrusionException { - try { - getValidDirectoryPath( context, input, allowNull); - return true; - } catch( Exception e ) { - return false; - } - } - - /** - * 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. - */ - public String getValidDirectoryPath(String context, String input, 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 ); - } - - // do basic validation - String canonical = getValidInput( context, input, "DirectoryName", 255, false); - - // get the canonical path without the drive letter if present - String cpath = new File(canonical).getCanonicalPath().replaceAll( "\\\\", "/"); - String temp = cpath.toLowerCase(); - if (temp.length() >= 2 && temp.charAt(0) >= 'a' && temp.charAt(0) <= 'z' && temp.charAt(1) == ':') { - cpath = cpath.substring(2); - } - - // prepare the input without the drive letter if present - String escaped = canonical.replaceAll( "\\\\", "/"); - temp = escaped.toLowerCase(); - if (temp.length() >= 2 && temp.charAt(0) >= 'a' && temp.charAt(0) <= 'z' && temp.charAt(1) == ':') { - escaped = escaped.substring(2); - } - - // the path is valid if the input matches the canonical path - if (!escaped.equals(cpath.toLowerCase())) { - 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 (IOException e) { - throw new ValidationException( context + ": Invalid directory name", "Invalid directory name does not exist: context=" + context + ", input=" + input, e, context ); - } - } - - /** - * ValidationErrorList variant of getValidDirectoryPath - */ - public String getValidDirectoryPath(String context, String input, boolean allowNull, ValidationErrorList errors) throws IntrusionException { - - try { - return getValidDirectoryPath(context, input, allowNull); - } catch (ValidationException e) { - errors.addError(context, e); - } - return input; - } - - - /** - * Returns true if input is a valid file name. - */ - public boolean isValidFileName(String context, String input, boolean allowNull) throws IntrusionException { - try { - getValidFileName( context, input, allowNull); - return true; - } catch( Exception e ) { - return false; - } - } - - /** - * 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. - */ - public String getValidFileName(String context, String input, boolean allowNull) throws ValidationException, IntrusionException { - String canonical = ""; - // detect path manipulation - try { - if (isEmpty(input)) { - if (allowNull) return null; - throw new ValidationException( context + ": Input file name required", "Input required: context=" + context + ", input=" + input, context ); - } - - // do basic validation - canonical = ESAPI.encoder().canonicalize(input); - getValidInput( context, input, "FileName", 255, true ); - - File f = new File(canonical); - String c = f.getCanonicalPath(); - String cpath = c.substring(c.lastIndexOf(File.separator) + 1); - - - // the path is valid if the input matches the canonical path - if (!input.equals(cpath.toLowerCase())) { - throw new ValidationException( context + ": Invalid file name", "Invalid directory name does not match the canonical path: context=" + context + ", input=" + input + ", canonical=" + canonical, context ); - } - - } catch (IOException e) { - throw new ValidationException( context + ": Invalid file name", "Invalid file name does not exist: context=" + context + ", canonical=" + canonical, e, context ); - } catch (EncodingException ee) { - throw new IntrusionException( context + ": Invalid file name", "Invalid file name: context=" + context + ", canonical=" + canonical, ee ); - } - - - // verify extensions - List extensions = ESAPI.securityConfiguration().getAllowedFileExtensions(); - Iterator i = extensions.iterator(); - while (i.hasNext()) { - String ext = (String) i.next(); - if (input.toLowerCase().endsWith(ext.toLowerCase())) { - return canonical; - } - } - throw new ValidationException( context + ": Invalid file name does not have valid extension ( "+ESAPI.securityConfiguration().getAllowedFileExtensions()+")", "Invalid file name does not have valid extension ( "+ESAPI.securityConfiguration().getAllowedFileExtensions()+"): context=" + context+", input=" + input, context ); - } - - /** - * 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. - */ - public String getValidFileName(String context, String input, boolean allowNull, ValidationErrorList errors) throws IntrusionException { - - try { - return getValidFileName(context, input, allowNull); - } catch (ValidationException e) { - errors.addError(context, e); - } - return input; - } - - /* - * Returns true if input is a valid number. - * - * @see org.owasp.esapi.interfaces.IValidator#isValidNumber(java.lang.String) - */ - public boolean isValidNumber(String context, String input, long minValue, long maxValue, boolean allowNull) throws IntrusionException { - try { - getValidNumber(context, input, minValue, maxValue, allowNull); - return true; - } catch( Exception e ) { - return false; - } - } - - /** - * 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. - */ - public Double getValidNumber(String context, String input, long minValue, long maxValue, boolean allowNull) throws ValidationException, IntrusionException { - Double minDoubleValue = new Double(minValue); - Double maxDoubleValue = new Double(maxValue); - return getValidDouble(context, input, minDoubleValue.doubleValue(), maxDoubleValue.doubleValue(), allowNull); - } - - public Double getValidNumber(String context, String input, long minValue, long maxValue, boolean allowNull, ValidationErrorList errors) throws IntrusionException { - - try { - return getValidNumber(context, input, minValue, maxValue, allowNull); - } catch (ValidationException e) { - errors.addError(context, e); - } - - //not sure what to return on error - return new Double(0); - } - - /* - * Returns true if input is a valid number. - * - * @see org.owasp.esapi.interfaces.IValidator#isValidNumber(java.lang.String) - */ - public boolean isValidDouble(String context, String input, double minValue, double maxValue, boolean allowNull) throws IntrusionException { - return isValidDouble( context, input, minValue, maxValue, allowNull ); - } - - /** - * 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. - */ - public Double getValidDouble(String context, String input, double minValue, double maxValue, boolean allowNull) throws ValidationException, IntrusionException { - if (minValue > maxValue) { - //should this be a RunTime? - throw new ValidationException( context + ": Invalid double input: context", "Validation parameter error for double: maxValue ( " + maxValue + ") must be greater than minValue ( " + minValue + ") for " + context, context ); - } - - if (isEmpty(input)) { - if (allowNull) return null; - throw new ValidationException( context + ": Input required: context", "Input required: context=" + context + ", input=" + input, context ); - } - - try { - Double d = new Double(Double.parseDouble(input)); - if (d.isInfinite()) throw new ValidationException( "Invalid double input: context=" + context, "Invalid double input is infinite: context=" + context + ", input=" + input, context ); - if (d.isNaN()) throw new ValidationException( "Invalid double input: context=" + context, "Invalid double input is infinite: context=" + context + ", input=" + input, context ); - if (d.doubleValue() < minValue) throw new ValidationException( "Invalid double input must be between " + minValue + " and " + maxValue + ": context=" + context, "Invalid double input must be between " + minValue + " and " + maxValue + ": context=" + context + ", input=" + input, context ); - if (d.doubleValue() > maxValue) throw new ValidationException( "Invalid double input must be between " + minValue + " and " + maxValue + ": context=" + context, "Invalid double input must be between " + minValue + " and " + maxValue + ": context=" + context + ", input=" + input, context ); - - return d; - } catch (NumberFormatException e) { - throw new ValidationException( context + ": Invalid double input", "Invalid double input format: context=" + context + ", input=" + input, e, context); - } - } - - public Double getValidDouble(String context, String input, double minValue, double maxValue, boolean allowNull, ValidationErrorList errors) throws IntrusionException { - - try { - return getValidDouble(context, input, minValue, maxValue, allowNull); - } catch (ValidationException e) { - errors.addError(context, e); - } - - //not sure what to return on error - return new Double(0); - } - - /* - * Returns true if input is a valid number. - * - * @see org.owasp.esapi.interfaces.IValidator#isValidInteger(java.lang.String) - */ - public boolean isValidInteger(String context, String input, int minValue, int maxValue, boolean allowNull) throws IntrusionException { - try { - getValidInteger( context, input, minValue, maxValue, allowNull); - return true; - } catch( Exception e ) { - return false; - } - } - - /** - * 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. - */ - public Integer getValidInteger(String context, String input, int minValue, int maxValue, boolean allowNull) throws ValidationException, IntrusionException { - if (minValue > maxValue) { - //should this be a RunTime? - throw new ValidationException( context + ": Invalid Integer", "Validation parameter error for double: maxValue ( " + maxValue + ") must be greater than minValue ( " + minValue + ") for " + context, context ); - } - - if (isEmpty(input)) { - if (allowNull) return null; - throw new ValidationException( context + ": Input required", "Input required: context=" + context + ", input=" + input, context ); - } - - try { - int i = Integer.parseInt(input); - if (i < minValue || i > maxValue ) throw new ValidationException( context + ": Invalid Integer. Value must be between " + minValue + " and " + maxValue, "Invalid int input must be between " + minValue + " and " + maxValue + ": context=" + context + ", input=" + input, context ); - return new Integer(i); - } catch (NumberFormatException e) { - throw new ValidationException( context + ": Invalid integer input", "Invalid int input: context=" + context + ", input=" + input, e, context ); - } - } - - public Integer getValidInteger(String context, String input, int minValue, int maxValue, boolean allowNull, ValidationErrorList errors) throws IntrusionException { - - try { - return getValidInteger(context, input, minValue, maxValue, allowNull); - } catch (ValidationException e) { - errors.addError(context, e); - } - - //not sure what to return on error - return new Integer(0); - } - - /** - * Returns true if input is valid file content. - */ - public boolean isValidFileContent(String context, byte[] input, int maxBytes, boolean allowNull) throws IntrusionException { - try { - getValidFileContent( context, input, maxBytes, allowNull); - return true; - } catch( Exception e ) { - return false; - } - } - - /** - * 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. - */ - public byte[] getValidFileContent(String context, byte[] input, int maxBytes, boolean allowNull) throws ValidationException, IntrusionException { - if (isEmpty(input)) { - if (allowNull) return null; - throw new ValidationException( context + ": Input required", "Input required: context=" + context + ", input=" + input, context ); - } - - long esapiMaxBytes = ESAPI.securityConfiguration().getAllowedFileUploadSize(); - if (input.length > esapiMaxBytes ) throw new ValidationException( context + ": Invalid file content can not exceed " + esapiMaxBytes + " bytes", "Exceeded ESAPI max length", context ); - if (input.length > maxBytes ) throw new ValidationException( context + ": Invalid file content can not exceed " + maxBytes + " bytes", "Exceeded maxBytes ( " + input.length + ")", context ); - - return input; - } - - public byte[] getValidFileContent(String context, byte[] input, int maxBytes, boolean allowNull, ValidationErrorList errors) throws IntrusionException { - - try { - return getValidFileContent(context, input, maxBytes, allowNull); - } catch (ValidationException e) { - errors.addError(context, e); - } - - //not sure what to return on error - return input; - } - - /** - * Returns true if a file upload has a valid name, path, and content. - */ - public boolean isValidFileUpload(String context, String directorypath, String filename, byte[] content, int maxBytes, boolean allowNull) throws IntrusionException { - return( isValidFileName( context, filename, allowNull ) && - isValidDirectoryPath( context, directorypath, allowNull ) && - isValidFileContent( context, content, maxBytes, allowNull ) ); - } - - /** - * 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. - */ - public void assertValidFileUpload(String context, String directorypath, String filename, byte[] content, int maxBytes, boolean allowNull) throws ValidationException, IntrusionException { - getValidFileName( context, filename, allowNull ); - getValidDirectoryPath( context, directorypath, allowNull ); - getValidFileContent( context, content, maxBytes, allowNull ); - } - - - /** - * ValidationErrorList variant of assertValidFileUpload - */ - public void assertValidFileUpload(String context, String filepath, String filename, byte[] content, int maxBytes, boolean allowNull, ValidationErrorList errors) - throws IntrusionException { - try { - assertValidFileUpload(context, filepath, filename, content, maxBytes, allowNull); - } catch (ValidationException e) { - errors.addError(context, e); - } - } - - /** - * 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 - */ - public boolean isValidHTTPRequest() throws IntrusionException { - try { - assertIsValidHTTPRequest(); - return true; - } catch( Exception e ) { - return false; - } - } - - /** - * 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. - */ - public boolean isValidHTTPRequest(HttpServletRequest request) throws IntrusionException { - try { - assertIsValidHTTPRequest(request); - return true; - } catch( Exception e ) { - return false; - } - } - - /** - * 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 - * - */ - public void assertIsValidHTTPRequest() throws ValidationException, IntrusionException { - HttpServletRequest request = ESAPI.httpUtilities().getCurrentRequest(); - assertIsValidHTTPRequest(request); - } - - /** - * 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. - */ - private void assertIsValidHTTPRequest(HttpServletRequest request) throws ValidationException, IntrusionException { - - if (request == null) { - throw new ValidationException( "Input required: HTTP request is null", "Input required: HTTP request is null" ); - } - - if ( !request.getMethod().equals( "GET") && !request.getMethod().equals("POST") ) { - throw new IntrusionException( "Bad HTTP method received", "Bad HTTP method received: " + request.getMethod() ); - } - - Iterator i1 = request.getParameterMap().entrySet().iterator(); - while (i1.hasNext()) { - Map.Entry entry = (Map.Entry) i1.next(); - String name = (String) entry.getKey(); - getValidInput( "HTTP request parameter: " + name, name, "HTTPParameterName", MAX_PARAMETER_NAME_LENGTH, false ); - String[] values = (String[]) entry.getValue(); - Iterator i3 = Arrays.asList(values).iterator(); - while (i3.hasNext()) { - String value = (String) i3.next(); - getValidInput( "HTTP request parameter: " + name, value, "HTTPParameterValue", MAX_PARAMETER_VALUE_LENGTH, true ); - } - } - - if (request.getCookies() != null) { - Iterator i2 = Arrays.asList(request.getCookies()).iterator(); - while (i2.hasNext()) { - Cookie cookie = (Cookie) i2.next(); - String name = cookie.getName(); - getValidInput( "HTTP request cookie: " + name, name, "HTTPCookieName", MAX_PARAMETER_NAME_LENGTH, true ); - String value = cookie.getValue(); - getValidInput( "HTTP request cookie: " + name, value, "HTTPCookieValue", MAX_PARAMETER_VALUE_LENGTH, true ); - } - } - - Enumeration e = request.getHeaderNames(); - while (e.hasMoreElements()) { - String name = (String) e.nextElement(); - if (name != null && !name.equalsIgnoreCase( "Cookie")) { - getValidInput( "HTTP request header: " + name, name, "HTTPHeaderName", MAX_PARAMETER_NAME_LENGTH, true ); - Enumeration e2 = request.getHeaders(name); - while (e2.hasMoreElements()) { - String value = (String) e2.nextElement(); - getValidInput( "HTTP request header: " + name, value, "HTTPHeaderValue", MAX_PARAMETER_VALUE_LENGTH, true ); - } - } - } - } - - /* - * Returns true if input is a valid list item. - * - * @see org.owasp.esapi.interfaces.IValidator#isValidListItem(java.util.List, - * java.lang.String) - */ - public boolean isValidListItem(String context, String input, List list) { - try { - getValidListItem( context, input, list); - return true; - } catch( Exception e ) { - return false; - } - } - - /** - * 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. - */ - public String getValidListItem(String context, String input, List list) throws ValidationException, IntrusionException { - if (list.contains(input)) return input; - throw new ValidationException( context + ": Invalid list item", "Invalid list item: context=" + context + ", input=" + input, context ); - } - - - /** - * ValidationErrorList variant of getValidListItem - */ - public String getValidListItem(String context, String input, List list, ValidationErrorList errors) throws IntrusionException { - - try { - return getValidListItem(context, input, list); - } catch (ValidationException e) { - errors.addError(context, e); - } - return input; - } - - /* - * Returns true if the parameters in the current request contain all required parameters and only optional ones in addition. - * - * @see org.owasp.esapi.interfaces.IValidator#isValidParameterSet(java.util.Set, - * java.util.Set, java.util.Set) - */ - public boolean isValidHTTPRequestParameterSet(String context, Set requiredNames, Set optionalNames) { - try { - assertIsValidHTTPRequestParameterSet( context, requiredNames, optionalNames); - return true; - } catch( Exception e ) { - return false; - } - } - - /** - * 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. - */ - public void assertIsValidHTTPRequestParameterSet(String context, Set required, Set optional) throws ValidationException, IntrusionException { - HttpServletRequest request = ESAPI.httpUtilities().getCurrentRequest(); - Set actualNames = request.getParameterMap().keySet(); - - // verify ALL required parameters are present - Set missing = new HashSet(required); - missing.removeAll(actualNames); - if (missing.size() > 0) { - throw new ValidationException( context + ": Invalid HTTP request missing parameters", "Invalid HTTP request missing parameters " + missing + ": context=" + context, context ); - } - - // verify ONLY optional + required parameters are present - Set extra = new HashSet(actualNames); - extra.removeAll(required); - extra.removeAll(optional); - if (extra.size() > 0) { - throw new ValidationException( context + ": Invalid HTTP request extra parameters " + extra, "Invalid HTTP request extra parameters " + extra + ": context=" + context, context ); - } - } - - /** - * ValidationErrorList variant of assertIsValidHTTPRequestParameterSet - */ - public void assertIsValidHTTPRequestParameterSet(String context, Set required, Set optional, ValidationErrorList errors) throws IntrusionException { - try { - assertIsValidHTTPRequestParameterSet(context, required, optional); - } catch (ValidationException e) { - errors.addError(context, e); - } - } - - /** - * 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) - * - * @see org.owasp.esapi.Validator#isValidASCIIFileContent(byte[]) - */ - public boolean isValidPrintable(String context, byte[] input, int maxLength, boolean allowNull) throws IntrusionException { - try { - getValidPrintable( context, input, maxLength, allowNull); - return true; - } catch( Exception e ) { - return false; - } - } - - /** - * 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. - */ - public byte[] getValidPrintable(String context, byte[] input, int maxLength, boolean allowNull) throws ValidationException, IntrusionException { - if (isEmpty(input)) { - if (allowNull) return null; - throw new ValidationException(context + ": Input bytes required", "Input bytes required: HTTP request is null", context ); - } - - if (input.length > maxLength) { - throw new ValidationException(context + ": Input bytes can not exceed " + maxLength + " bytes", "Input exceeds maximum allowed length of " + maxLength + " by " + (input.length-maxLength) + " bytes: context=" + context + ", input=" + input, context); - } - - for (int i = 0; i < input.length; i++) { - if (input[i] < 33 || input[i] > 126) { - throw new ValidationException(context + ": Invalid input bytes: context=" + context, "Invalid non-ASCII input bytes, context=" + context + ", input=" + input, context); - } - } - return input; - } - - /** - * ValidationErrorList variant of getValidPrintable - */ - public byte[] getValidPrintable(String context, byte[] input,int maxLength, boolean allowNull, ValidationErrorList errors) - throws IntrusionException { - - try { - return getValidPrintable(context, input, maxLength, allowNull); - } catch (ValidationException e) { - errors.addError(context, e); - } - return input; - } - - - /* - * Returns true if input is valid printable ASCII characters (32-126). - * - * @see org.owasp.esapi.interfaces.IValidator#isValidPrintable(java.lang.String) - */ - public boolean isValidPrintable(String context, String input, int maxLength, boolean allowNull) throws IntrusionException { - try { - getValidPrintable( context, input, maxLength, allowNull); - return true; - } catch( Exception e ) { - return false; - } - } - - /** - * 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. - */ - public String getValidPrintable(String context, String input, int maxLength, boolean allowNull) throws ValidationException, IntrusionException { - String canonical = ""; - try { - canonical = ESAPI.encoder().canonicalize(input); - return new String( getValidPrintable( context, canonical.getBytes(), maxLength, allowNull) ); - } catch (EncodingException e) { - throw new ValidationException( context + ": Invalid printable input", "Invalid encoding of printable input, context=" + context + ", input=" + input, e, context); - } - } - - /** - * ValidationErrorList variant of getValidPrintable - */ - public String getValidPrintable(String context, String input,int maxLength, boolean allowNull, ValidationErrorList errors) - throws IntrusionException { - - try { - return getValidPrintable(context, input, maxLength, allowNull); - } catch (ValidationException e) { - errors.addError(context, e); - } - return input; - } - - - /** - * Returns true if input is a valid redirect location. - */ - public boolean isValidRedirectLocation(String context, String input, boolean allowNull) throws IntrusionException { - return ESAPI.validator().isValidInput( context, input, "Redirect", 512, allowNull); - } - - - /** - * 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 String getValidRedirectLocation(String context, String input, boolean allowNull) throws ValidationException, IntrusionException { - return ESAPI.validator().getValidInput( context, input, "Redirect", 512, allowNull); - } - - /** - * ValidationErrorList variant of getValidRedirectLocation - */ - public String getValidRedirectLocation(String context, String input, boolean allowNull, ValidationErrorList errors) throws IntrusionException { - - try { - return getValidRedirectLocation(context, input, allowNull); - } catch (ValidationException e) { - errors.addError(context, e); - } - return input; - } - - /** - * This implementation reads until a newline or the specified number of - * characters. - * - * @param in - * the in - * @param max - * the max - * @return the string - * @throws ValidationException - * the validation exception - * @see org.owasp.esapi.Validator#safeReadLine(java.io.InputStream, - * int) - */ - public String safeReadLine(InputStream in, int max) throws ValidationException { - if (max <= 0) - throw new ValidationAvailabilityException( "Invalid input", "Invalid readline. Must read a positive number of bytes from the stream"); - - StringBuffer sb = new StringBuffer(); - int count = 0; - int c; - - try { - while (true) { - c = in.read(); - if ( c == -1 ) { - if (sb.length() == 0) return null; - break; - } - if (c == '\n' || c == '\r') break; - count++; - if (count > max) { - throw new ValidationAvailabilityException( "Invalid input", "Invalid readLine. Read more than maximum characters allowed (" + max + ")"); - } - sb.append((char) c); - } - return sb.toString(); - } catch (IOException e) { - throw new ValidationAvailabilityException( "Invalid input", "Invalid readLine. Problem reading from input stream", e); - } - } - - /** - * Helper function to check if a String is empty - * - * @param input string input value - * @return boolean response if input is empty or not - */ - private final boolean isEmpty(String input) { - return (input==null || input.trim().length() == 0); - } - - /** - * Helper function to check if a byte array is empty - * - * @param input string input value - * @return boolean response if input is empty or not - */ - private final boolean isEmpty(byte[] input) { - return (input==null || input.length == 0); - } -} diff --git a/src/org/owasp/esapi/reference/FileBasedAccessController.java b/src/org/owasp/esapi/reference/FileBasedAccessController.java deleted file mode 100644 index fe6d6c71a..000000000 --- a/src/org/owasp/esapi/reference/FileBasedAccessController.java +++ /dev/null @@ -1,440 +0,0 @@ -/** - * 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.reference; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; - -import org.owasp.esapi.ESAPI; -import org.owasp.esapi.Logger; -import org.owasp.esapi.User; -import org.owasp.esapi.errors.AccessControlException; -import org.owasp.esapi.errors.EncodingException; -import org.owasp.esapi.errors.IntrusionException; - -/** - * 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 /
  • - *
- * - * @author Jeff Williams (jeff.williams@aspectsecurity.com) - * @since June 1, 2007 - * @see org.owasp.esapi.AccessController - */ -public class FileBasedAccessController implements org.owasp.esapi.AccessController { - - /** The url map. */ - private Map urlMap = new HashMap(); - - /** The function map. */ - private Map functionMap = new HashMap(); - - /** The data map. */ - private Map dataMap = new HashMap(); - - /** The file map. */ - private Map fileMap = new HashMap(); - - /** The service map. */ - private Map serviceMap = new HashMap(); - - /** The deny. */ - private Rule deny = new Rule(); - - /** The logger. */ - private Logger logger = ESAPI.getLogger("AccessController"); - - public FileBasedAccessController() { - } - - public boolean isAuthorizedForURL(String url) { - try { - assertAuthorizedForURL( url ); - return true; - } catch ( Exception e ) { - return false; - } - } - - public boolean isAuthorizedForFunction(String functionName) { - try { - assertAuthorizedForFunction( functionName ); - return true; - } catch ( Exception e ) { - return false; - } - } - - public boolean isAuthorizedForData(String key) { - try { - assertAuthorizedForData( key ); - return true; - } catch ( Exception e ) { - return false; - } - } - - public boolean isAuthorizedForFile(String filepath) { - try { - assertAuthorizedForFile( filepath ); - return true; - } catch ( Exception e ) { - return false; - } - } - - public boolean isAuthorizedForService(String serviceName) { - try { - assertAuthorizedForService( serviceName ); - return true; - } catch ( Exception e ) { - return false; - } - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IAccessController#isAuthorizedForURL(java.lang.String, - * java.lang.String) - */ - public void assertAuthorizedForURL(String url) throws AccessControlException { - if (urlMap==null || urlMap.isEmpty()) { - urlMap = loadRules("URLAccessRules.txt"); - } - if ( !matchRule(urlMap, url) ) { - throw new AccessControlException("Not authorized for URL", "Not authorized for URL: " + url ); - } - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IAccessController#isAuthorizedForFunction(java.lang.String, - * java.lang.String) - */ - public void assertAuthorizedForFunction(String functionName) throws AccessControlException { - if (functionMap==null || functionMap.isEmpty()) { - functionMap = loadRules("FunctionAccessRules.txt"); - } - if ( !matchRule(functionMap, functionName) ) { - throw new AccessControlException("Not authorized for function", "Not authorized for function: " + functionName ); - } - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IAccessController#isAuthorizedForData(java.lang.String) - */ - public void assertAuthorizedForData(String key) throws AccessControlException { - if (dataMap==null || dataMap.isEmpty()) { - dataMap = loadRules("DataAccessRules.txt"); - } - if ( !matchRule(dataMap, key) ) { - throw new AccessControlException("Not authorized for function", "Not authorized for data: " + key ); - } - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IAccessController#isAuthorizedForFile(java.lang.String, - * java.lang.String) - */ - public void assertAuthorizedForFile(String filepath) throws AccessControlException { - if (fileMap==null || fileMap.isEmpty()) { - fileMap = loadRules("FileAccessRules.txt"); - } - if ( !matchRule(fileMap, filepath.replaceAll("\\\\","/"))) { - throw new AccessControlException("Not authorized for file", "Not authorized for file: " + filepath ); - } - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IAccessController#isAuthorizedForBackendService(java.lang.String, - * java.lang.String) - */ - public void assertAuthorizedForService(String serviceName) throws AccessControlException { - if (serviceMap==null || serviceMap.isEmpty()) { - serviceMap = loadRules("ServiceAccessRules.txt"); - } - if ( !matchRule(serviceMap, serviceName ) ) { - throw new AccessControlException("Not authorized for service", "Not authorized for service: " + serviceName ); - } - } - - /** - * Match rule. - * - * @param map - * the map - * @param path - * the path - * - * @return true, if successful - * - * @throws AccessControlException - * the access control exception - */ - private boolean matchRule(Map map, String path) { - // get users roles - User user = ESAPI.authenticator().getCurrentUser(); - Set roles = user.getRoles(); - // search for the first rule that matches the path and rules - Rule rule = searchForRule(map, roles, path); - return rule.allow; - } - - /** - * Search for rule. Four mapping rules are used in 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 servlet, specified by the single character pattern / - * - * @param map - * the map - * @param roles - * the roles - * @param path - * the path - * - * @return the rule - * - * @throws AccessControlException - * the access control exception - */ - private Rule searchForRule(Map map, Set roles, String path) { - String canonical = null; - try { - canonical = ESAPI.encoder().canonicalize(path); - } catch (EncodingException e) { - logger.warning( Logger.SECURITY, "Failed to canonicalize input: " + path ); - } - - String part = canonical; - while (part.endsWith("/")) { - part = part.substring(0, part.length() - 1); - } - - if (part.indexOf("..") != -1) { - throw new IntrusionException("Attempt to manipulate access control path", "Attempt to manipulate access control path: " + path ); - } - - // extract extension if any - String extension = ""; - int extIndex = part.lastIndexOf("."); - if (extIndex != -1) { - extension = part.substring(extIndex + 1); - } - - // Check for exact match - ignore any ending slash - Rule rule = (Rule) map.get(part); - - // Check for ending with /* - if (rule == null) - rule = (Rule) map.get(part + "/*"); - - // Check for matching extension rule *.ext - if (rule == null) - rule = (Rule) map.get("*." + extension); - - // if rule found and user's roles match rules' roles, return the rule - if (rule != null && overlap(rule.roles, roles)) - return rule; - - // rule hasn't been found - if there are no more parts, return a deny - int slash = part.lastIndexOf('/'); - if ( slash == -1 ) { - return deny; - } - - // if there are more parts, strip off the last part and recurse - part = part.substring(0, part.lastIndexOf('/')); - - // return default deny - if (part.length() <= 1) { - return deny; - } - - return searchForRule(map, roles, part); - } - - /** - * Return true if there is overlap between the two sets. - * - * @param ruleRoles - * the rule roles - * @param userRoles - * the user roles - * - * @return true, if successful - */ - private boolean overlap(Set ruleRoles, Set userRoles) { - if (ruleRoles.contains("any")) { - return true; - } - Iterator i = userRoles.iterator(); - while (i.hasNext()) { - String role = (String) i.next(); - if (ruleRoles.contains(role)) { - return true; - } - } - return false; - } - - /** - * Load rules. - * - * @param f - * the f - * - * @return the hash map - * - * @throws AccessControlException - * the access control exception - */ - private Map loadRules(String ruleset) { - Map map = new HashMap(); - InputStream is = null; - try { - is = new FileInputStream(new File(ESAPI.securityConfiguration().getResourceDirectory(), ruleset)); - String line = ""; - while ((line = ESAPI.validator().safeReadLine(is, 500)) != null) { - if (line.length() > 0 && line.charAt(0) != '#') { - Rule rule = new Rule(); - String[] parts = line.split("\\|"); - // fix Windows paths - rule.path = parts[0].trim().replaceAll("\\\\", "/"); - rule.roles.add(parts[1].trim().toLowerCase()); - String action = parts[2].trim(); - rule.allow = action.equalsIgnoreCase("allow"); - if (map.containsKey(rule.path)) { - logger.warning( Logger.SECURITY, "Problem in access control file. Duplicate rule ignored: " + rule); - } else { - map.put(rule.path, rule); - } - } - } - } catch (Exception e) { - logger.warning( Logger.SECURITY, "Problem in access control file : " + ruleset, e ); - } finally { - try { - if (is != null) { - is.close(); - } - } catch (IOException e) { - logger.warning(Logger.SECURITY, "Failure closing access control file : " + ruleset, e); - } - } - return map; - } - - /** - * The Class Rule. - */ - private class Rule { - - /** The path. */ - protected String path = ""; - - /** The roles. */ - protected Set roles = new HashSet(); - - /** The allow. */ - protected boolean allow = false; - - /** - * Creates a new Rule object. - */ - protected Rule() { - // to replace synthetic accessor method - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - public String toString() { - return "URL:" + path + " | " + roles + " | " + (allow ? "allow" : "deny"); - } - } -} diff --git a/src/org/owasp/esapi/reference/FileBasedAuthenticator.java b/src/org/owasp/esapi/reference/FileBasedAuthenticator.java deleted file mode 100644 index fea6af10a..000000000 --- a/src/org/owasp/esapi/reference/FileBasedAuthenticator.java +++ /dev/null @@ -1,914 +0,0 @@ -/** - * 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.reference; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.owasp.esapi.ESAPI; -import org.owasp.esapi.HTTPUtilities; -import org.owasp.esapi.Logger; -import org.owasp.esapi.Randomizer; -import org.owasp.esapi.User; -import org.owasp.esapi.errors.AccessControlException; -import org.owasp.esapi.errors.AuthenticationAccountsException; -import org.owasp.esapi.errors.AuthenticationCredentialsException; -import org.owasp.esapi.errors.AuthenticationException; -import org.owasp.esapi.errors.AuthenticationLoginException; -import org.owasp.esapi.errors.EncryptionException; - -/** - * 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
- * 
- * 
- * - * @author Jeff Williams at Aspect Security - * @since June 1, 2007 - * @see org.owasp.esapi.Authenticator - */ -public class FileBasedAuthenticator implements org.owasp.esapi.Authenticator { - - /** Key for user in session */ - protected static final String USER = "ESAPIUserSessionKey"; - - /** The logger. */ - private final Logger logger = ESAPI.getLogger("Authenticator"); - - /** The file that contains the user db */ - private File userDB = null; - - /** How frequently to check the user db for external modifications */ - private long checkInterval = 60 * 1000; - - /** The last modified time we saw on the user db. */ - private long lastModified = 0; - - /** The last time we checked if the user db had been modified externally */ - private long lastChecked = 0; - - private final int MAX_ACCOUNT_NAME_LENGTH = 250; - - /** - * 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: - *

-     * 
-     * java -Dorg.owasp.esapi.resources="/path/resources" -classpath esapi.jar org.owasp.esapi.Authenticator alice password admin
-     * 
-     * 
- * - * @param args the args - * @throws AuthenticationException the authentication exception - */ - public static void main(String[] args) throws Exception { - if (args.length != 3) { - System.out.println("Usage: Authenticator accountname password role"); - return; - } - FileBasedAuthenticator auth = new FileBasedAuthenticator(); - String accountName = args[0].toLowerCase(); - String password = args[1]; - String role = args[2]; - DefaultUser user = (DefaultUser) auth.getUser(args[0]); - if (user == null) { - user = new DefaultUser(accountName); - String newHash = auth.hashPassword(password, accountName); - auth.setHashedPassword(user, newHash); - user.addRole(role); - user.enable(); - user.unlock(); - auth.userMap.put(new Long(user.getAccountId()), user); - System.out.println("New user created: " + accountName); - auth.saveUsers(); - System.out.println("User account " + user.getAccountName() + " updated"); - } else { - System.err.println("User account " + user.getAccountName() + " already exists!"); - } - } - - private void setHashedPassword(User user, String hash) { - List hashes = getAllHashedPasswords(user, true); - hashes.add( 0, hash); - if (hashes.size() > ESAPI.securityConfiguration().getMaxOldPasswordHashes() ) - hashes.remove( hashes.size() - 1 ); - logger.info(Logger.SECURITY, "New hashed password stored for " + user.getAccountName() ); - } - - String getHashedPassword(User user) { - List hashes = getAllHashedPasswords(user, false); - return (String) hashes.get(0); - } - - void setOldPasswordHashes(User user, List oldHashes) { - List hashes = getAllHashedPasswords(user, true); - if (hashes.size() > 1) - hashes.removeAll(hashes.subList(1, hashes.size()-1)); - hashes.addAll(oldHashes); - } - - List getAllHashedPasswords(User user, boolean create) { - List hashes = (List) passwordMap.get(user); - if (hashes != null) - return hashes; - if (create) { - hashes = new ArrayList(); - passwordMap.put(user, hashes); - return hashes; - } - throw new RuntimeException("No hashes found for " + user.getAccountName() + ". Is User.hashcode() and equals() implemented correctly?"); - } - - List getOldPasswordHashes(User user) { - List hashes = getAllHashedPasswords(user, false); - if (hashes.size() > 1) - return Collections.unmodifiableList(hashes.subList(1, hashes.size()-1)); - return Collections.EMPTY_LIST; - } - - /** The user map. */ - private Map userMap = new HashMap(); - - // Map>, where the strings are password hashes, with the current hash in entry 0 - private Map passwordMap = new Hashtable(); - - /* - * The currentUser ThreadLocal variable is used to make the currentUser available to any call in any part of an - * application. Otherwise, each thread would have to pass the User object through the calltree to any methods that - * need it. Because we want exceptions and log calls to contain user data, that could be almost anywhere. Therefore, - * the ThreadLocal approach simplifies things greatly.

As a possible extension, one could create a delegation - * framework by adding another ThreadLocal to hold the delegating user identity. - */ - private ThreadLocalUser currentUser = new ThreadLocalUser(); - - private class ThreadLocalUser extends InheritableThreadLocal { - - public Object initialValue() { - return User.ANONYMOUS; - } - - public User getUser() { - return (User)super.get(); - } - - public void setUser(User newUser) { - super.set(newUser); - } - }; - - public FileBasedAuthenticator() { - } - - /** - * 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. - */ - public void clearCurrent() { - // logger.logWarning(Logger.SECURITY, "************Clearing threadlocals. Thread" + Thread.currentThread().getName() ); - currentUser.setUser(null); - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IAuthenticator#createAccount(java.lang.String, java.lang.String) - */ - public synchronized User createUser(String accountName, String password1, String password2) throws AuthenticationException { - loadUsersIfNecessary(); - if (accountName == null) { - throw new AuthenticationAccountsException("Account creation failed", "Attempt to create user with null accountName"); - } - if (getUser(accountName) != null) { - throw new AuthenticationAccountsException("Account creation failed", "Duplicate user creation denied for " + accountName); - } - - verifyAccountNameStrength(accountName); - - if ( password1 == null ) { - throw new AuthenticationCredentialsException( "Invalid account name", "Attempt to create account " + accountName + " with a null password" ); - } - verifyPasswordStrength(null, password1); - - if (!password1.equals(password2)) throw new AuthenticationCredentialsException("Passwords do not match", "Passwords for " + accountName + " do not match"); - - DefaultUser user = new DefaultUser(accountName); - try { - setHashedPassword( user, hashPassword(password1, accountName) ); - } catch (EncryptionException ee) { - throw new AuthenticationException("Internal error", "Error hashing password for " + accountName, ee); - } - userMap.put(new Long( user.getAccountId() ), user); - logger.info(Logger.SECURITY, "New user created: " + accountName); - saveUsers(); - return user; - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IAuthenticator#exists(java.lang.String) - */ - public boolean exists(String accountName) { - return getUser(accountName) != null; - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IAuthenticator#generateStrongPassword(int, char[]) - */ - public String generateStrongPassword() { - return generateStrongPassword(""); - } - - private String generateStrongPassword(String oldPassword) { - Randomizer r = ESAPI.randomizer(); - int letters = r.getRandomInteger(4, 6); // inclusive, exclusive - int digits = 7-letters; - String passLetters = r.getRandomString(letters, DefaultEncoder.CHAR_PASSWORD_LETTERS ); - String passDigits = r.getRandomString( digits, DefaultEncoder.CHAR_PASSWORD_DIGITS ); - String passSpecial = r.getRandomString( 1, DefaultEncoder.CHAR_PASSWORD_SPECIALS ); - String newPassword = passLetters + passSpecial + passDigits; - return newPassword; - } - - /* (non-Javadoc) - * @see org.owasp.esapi.interfaces.IAuthenticator#changePassword(org.owasp.esapi.interfaces.IUser, java.lang.String, java.lang.String, java.lang.String) - */ - public void changePassword(User user, String currentPassword, - String newPassword, String newPassword2) - throws AuthenticationException { - String accountName = user.getAccountName(); - try { - String currentHash = getHashedPassword(user); - String verifyHash = hashPassword(currentPassword, accountName); - if (!currentHash.equals(verifyHash)) { - throw new AuthenticationCredentialsException("Password change failed", "Authentication failed for password change on user: " + accountName ); - } - if (newPassword == null || newPassword2 == null || !newPassword.equals(newPassword2)) { - throw new AuthenticationCredentialsException("Password change failed", "Passwords do not match for password change on user: " + accountName ); - } - verifyPasswordStrength(currentPassword, newPassword); - ((DefaultUser)user).setLastPasswordChangeTime(new Date()); - String newHash = hashPassword(newPassword, accountName); - if (getOldPasswordHashes(user).contains(newHash)) { - throw new AuthenticationCredentialsException( "Password change failed", "Password change matches a recent password for user: " + accountName ); - } - setHashedPassword(user, newHash); - logger.info(Logger.SECURITY, "Password changed for user: " + accountName ); - } catch (EncryptionException ee) { - throw new AuthenticationException("Password change failed", "Encryption exception changing password for " + accountName, ee); - } - } - - - /* (non-Javadoc) - * @see org.owasp.esapi.interfaces.IAuthenticator#verifyPassword(org.owasp.esapi.interfaces.IUser, java.lang.String) - */ - public boolean verifyPassword(User user, String password) { - String accountName = user.getAccountName(); - try { - String hash = hashPassword(password, accountName); - String currentHash = getHashedPassword(user); - if (hash.equals(currentHash)) { - ((DefaultUser)user).setLastLoginTime(new Date()); - ((DefaultUser)user).setFailedLoginCount(0); - logger.info(Logger.SECURITY, "Password verified for " + accountName ); - return true; - } - } catch( EncryptionException e ) { - logger.fatal(Logger.SECURITY, "Encryption error verifying password for " + accountName ); - } - logger.fatal(Logger.SECURITY, "Password verification failed for " + accountName ); - return false; - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IAuthenticator#generateStrongPassword(int, char[]) - */ - public String generateStrongPassword(User user, String oldPassword) { - String newPassword = generateStrongPassword(oldPassword); - if (newPassword != null) - logger.info(Logger.SECURITY, "Generated strong password for " + user.getAccountName()); - return newPassword; - } - - /* - * Returns the currently logged user as set by the setCurrentUser() methods. Must not log in this method because the - * logger calls getCurrentUser() and this could cause a loop. - * - * @see org.owasp.esapi.interfaces.IAuthenticator#getCurrentUser() - */ - public User getCurrentUser() { - User user = (User) currentUser.get(); - if (user == null) { - user = User.ANONYMOUS; - } - return user; - } - - - /** - * Gets the user object with the matching account name or null if there is no match. - * - * @param accountName the account name - * @return the user, or null if not matched. - */ - public synchronized User getUser(long accountId) { - if ( accountId == 0 ) { - return User.ANONYMOUS; - } - loadUsersIfNecessary(); - User user = (User) userMap.get(new Long( accountId )); - return user; - } - - /** - * Gets the user object with the matching account name or null if there is no match. - * - * @param accountName the account name - * @return the user, or null if not matched. - */ - public synchronized User getUser(String accountName) { - if ( accountName == null ) { - return User.ANONYMOUS; - } - loadUsersIfNecessary(); - Iterator i = userMap.values().iterator(); - while( i.hasNext() ) { - User u = (User)i.next(); - if ( u.getAccountName().equalsIgnoreCase(accountName) ) return u; - } - return null; - } - - - /** - * Gets the user from session. - * - * @param request the request - * @return the user from session - */ - protected User getUserFromSession() { - HttpSession session = ESAPI.httpUtilities().getCurrentRequest().getSession(); - return (User)session.getAttribute(USER); - } - - /** - * Returns the user if a matching remember token is found, or null if the token - * is missing, token is corrupt, token is expired, account name does not match - * and existing account, or hashed password does not match user's hashed password. - */ - protected DefaultUser getUserFromRememberToken() { - Cookie token = ESAPI.httpUtilities().getCookie( ESAPI.currentRequest(), HTTPUtilities.REMEMBER_TOKEN_COOKIE_NAME ); - if ( token == null ) { - return null; - } - - String[] data = null; - try { - data = ESAPI.encryptor().unseal( token.getValue() ).split( ":" ); - } catch (EncryptionException e) { - logger.warning(Logger.SECURITY, "Found corrupt or expired remember token" ); - ESAPI.httpUtilities().killCookie( ESAPI.currentRequest(), ESAPI.currentResponse(), HTTPUtilities.REMEMBER_TOKEN_COOKIE_NAME ); - return null; - } - - if ( data.length != 3 ) { - return null; - } - // data[0] is a random nonce, which can be ignored - String username = data[1]; - String password = data[2]; - DefaultUser user = (DefaultUser) getUser( username ); - if ( user == null ) { - logger.warning( Logger.SECURITY, "Found valid remember token but no user matching " + username ); - return null; - } - - logger.warning( Logger.SECURITY, "Logging in user with remember token: " + user.getAccountName() ); - try { - user.loginWithPassword(password); - } catch (AuthenticationException ae) { - logger.warning( Logger.SECURITY, "Login via remember me cookie failed for user " + username, ae); - ESAPI.httpUtilities().killCookie( ESAPI.currentRequest(), ESAPI.currentResponse(), HTTPUtilities.REMEMBER_TOKEN_COOKIE_NAME ); - return null; - } - return user; - } - - /** - * Gets the user names. - * - * @return list of user account names - */ - public synchronized Set getUserNames() { - loadUsersIfNecessary(); - HashSet results = new HashSet(); - Iterator i = userMap.values().iterator(); - while( i.hasNext() ) { - User u = (User)i.next(); - results.add( u.getAccountName() ); - } - return results; - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IAuthenticator#hashPassword(java.lang.String, java.lang.String) - */ - public String hashPassword(String password, String accountName) throws EncryptionException { - String salt = accountName.toLowerCase(); - return ESAPI.encryptor().hash(password, salt); - } - - /** - * Load users. - * - * @return the hash map - * @throws AuthenticationException the authentication exception - */ - protected void loadUsersIfNecessary() { - if (userDB == null) { - userDB = new File((ESAPI.securityConfiguration()).getResourceDirectory(), "users.txt"); - } - - // We only check at most every checkInterval milliseconds - long now = System.currentTimeMillis(); - if (now - lastChecked < checkInterval) { - return; - } - lastChecked = now; - - if (lastModified == userDB.lastModified()) { - return; - } - loadUsersImmediately(); - } - - // file was touched so reload it - protected void loadUsersImmediately() { - synchronized( this ) { - logger.trace(Logger.SECURITY, "Loading users from " + userDB.getAbsolutePath(), null); - - BufferedReader reader = null; - try { - HashMap map = new HashMap(); - reader = new BufferedReader(new FileReader(userDB)); - String line = null; - while ((line = reader.readLine()) != null) { - if (line.length() > 0 && line.charAt(0) != '#') { - DefaultUser user = createUser(line); - if (map.containsKey( new Long( user.getAccountId()))) { - logger.fatal(Logger.SECURITY, "Problem in user file. Skipping duplicate user: " + user, null); - } - map.put( new Long( user.getAccountId() ), user); - } - } - userMap = map; - this.lastModified = System.currentTimeMillis(); - logger.trace(Logger.SECURITY, "User file reloaded: " + map.size(), null); - } catch (Exception e) { - logger.fatal(Logger.SECURITY, "Failure loading user file: " + userDB.getAbsolutePath(), e); - } finally { - try { - if (reader != null) { - reader.close(); - } - } catch (IOException e) { - logger.fatal(Logger.SECURITY, "Failure closing user file: " + userDB.getAbsolutePath(), e); - } - } - } - } - - private DefaultUser createUser(String line) throws AuthenticationException { - String[] parts = line.split(" *\\| *"); - String accountIdString = parts[0]; - long accountId = Long.parseLong(accountIdString); - String accountName = parts[1]; - - verifyAccountNameStrength( accountName ); - DefaultUser user = new DefaultUser( accountName ); - user.accountId = accountId; - - String password = parts[2]; - verifyPasswordStrength(null, password); - setHashedPassword(user, password); - - String[] roles = parts[3].toLowerCase().split(" *, *"); - for (int i=0; i 16 (where character sets are upper, lower, digit, and special (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IAuthenticator#verifyPasswordStrength(java.lang.String) - */ - public void verifyPasswordStrength(String oldPassword, String newPassword) throws AuthenticationException { - if ( oldPassword == null ) oldPassword = ""; - if ( newPassword == null ) throw new AuthenticationCredentialsException("Invalid password", "New password cannot be null" ); - - // can't change to a password that contains any 3 character substring of old password - int length = oldPassword.length(); - for (int i = 0; i < length - 2; i++) { - String sub = oldPassword.substring(i, i + 3); - if (newPassword.indexOf(sub) > -1 ) { - throw new AuthenticationCredentialsException("Invalid password", "New password cannot contain pieces of old password" ); - } - } - - // new password must have enough character sets and length - int charsets = 0; - for (int i = 0; i < newPassword.length(); i++) - if (Arrays.binarySearch(DefaultEncoder.CHAR_LOWERS, newPassword.charAt(i)) > 0) { - charsets++; - break; - } - for (int i = 0; i < newPassword.length(); i++) - if (Arrays.binarySearch(DefaultEncoder.CHAR_UPPERS, newPassword.charAt(i)) > 0) { - charsets++; - break; - } - for (int i = 0; i < newPassword.length(); i++) - if (Arrays.binarySearch(DefaultEncoder.CHAR_DIGITS, newPassword.charAt(i)) > 0) { - charsets++; - break; - } - for (int i = 0; i < newPassword.length(); i++) - if (Arrays.binarySearch(DefaultEncoder.CHAR_SPECIALS, newPassword.charAt(i)) > 0) { - charsets++; - break; - } - - // calculate and verify password strength - int strength = newPassword.length() * charsets; - if (strength < 16) { - throw new AuthenticationCredentialsException("Invalid password", "New password is not long and complex enough"); - } - } - -} diff --git a/src/org/owasp/esapi/reference/IntegerAccessReferenceMap.java b/src/org/owasp/esapi/reference/IntegerAccessReferenceMap.java deleted file mode 100644 index 7a7aead44..000000000 --- a/src/org/owasp/esapi/reference/IntegerAccessReferenceMap.java +++ /dev/null @@ -1,154 +0,0 @@ -/** - * 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.reference; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Set; -import java.util.TreeSet; - -import org.owasp.esapi.AccessReferenceMap; -import org.owasp.esapi.errors.AccessControlException; - -/** - * Reference implementation of the AccessReferenceMap interface. This - * implementation generates integers for indirect references. - * - * @author Jeff Williams (jeff.williams@aspectsecurity.com) - * @since June 1, 2007 - * @see org.owasp.esapi.AccessReferenceMap - */ -public class IntegerAccessReferenceMap implements AccessReferenceMap { - - /** The itod (indirect to direct) */ - HashMap itod = new HashMap(); - - /** The dtoi (direct to indirect) */ - HashMap dtoi = new HashMap(); - - int count = 1; - - /** - * This AccessReferenceMap implementation uses integers to - * create a layer of indirection. - */ - public IntegerAccessReferenceMap() { - // call update to set up the references - } - - /** - * Instantiates a new access reference map. - * - * @param directReferences - * the direct references - */ - public IntegerAccessReferenceMap(Set directReferences) { - update(directReferences); - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.AccessReferenceMap#iterator() - */ - public Iterator iterator() { - TreeSet sorted = new TreeSet(dtoi.keySet()); - return sorted.iterator(); - } - - /** - * Adds a direct reference and a new indirect reference, overwriting any existing values. - * @param direct - */ - public String addDirectReference(Object direct) { - if ( dtoi.keySet().contains( direct ) ) { - return (String)dtoi.get( direct ); - } - String indirect = getUniqueReference(); - itod.put(indirect, direct); - dtoi.put(direct, indirect); - return indirect; - } - - private synchronized String getUniqueReference() { - return "" + count++; // returns a string version of the counter - } - - /** - * Remove a direct reference and the corresponding indirect reference. - * @param direct - */ - public String removeDirectReference(Object direct) throws AccessControlException { - String indirect = (String)dtoi.get(direct); - if ( indirect != null ) { - itod.remove(indirect); - dtoi.remove(direct); - } - return indirect; - } - - /** - * 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. - * - * @param directReferences - * the direct references - */ - final public void update(Set directReferences) { - HashMap dtoi_old = (HashMap) dtoi.clone(); - dtoi.clear(); - itod.clear(); - - Iterator i = directReferences.iterator(); - while (i.hasNext()) { - Object direct = i.next(); - - // get the old indirect reference - String indirect = (String) dtoi_old.get(direct); - - // if the old reference is null, then create a new one that doesn't - // collide with any existing indirect references - if (indirect == null) { - indirect = getUniqueReference(); - } - itod.put(indirect, direct); - dtoi.put(direct, indirect); - } - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IAccessReferenceMap#getIndirectReference(java.lang.String) - */ - public String getIndirectReference(Object directReference) { - return (String) dtoi.get(directReference); - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IAccessReferenceMap#getDirectReference(java.lang.String) - */ - public Object getDirectReference(String indirectReference) throws AccessControlException { - if (itod.containsKey(indirectReference)) { - return itod.get(indirectReference); - } - throw new AccessControlException("Access denied", "Request for invalid indirect reference: " + indirectReference); - } -} diff --git a/src/org/owasp/esapi/reference/JavaEncryptor.java b/src/org/owasp/esapi/reference/JavaEncryptor.java deleted file mode 100644 index 54311435f..000000000 --- a/src/org/owasp/esapi/reference/JavaEncryptor.java +++ /dev/null @@ -1,278 +0,0 @@ -/** - * 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.reference; - -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.SecureRandom; -import java.security.Signature; -import java.util.Date; - -import javax.crypto.Cipher; -import javax.crypto.SecretKey; -import javax.crypto.SecretKeyFactory; -import javax.crypto.spec.PBEParameterSpec; - -import org.owasp.esapi.ESAPI; -import org.owasp.esapi.errors.EncryptionException; -import org.owasp.esapi.errors.IntegrityException; - -/** - * Reference implementation of the Encryptor interface. This implementation - * layers on the JCE provided cryptographic package. Algorithms used are - * configurable in the ESAPI.properties file. - * - * - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security - * @since June 1, 2007 - * @see org.owasp.esapi.Encryptor - */ -public class JavaEncryptor implements org.owasp.esapi.Encryptor { - - /** The private key. */ - PrivateKey privateKey = null; - - /** The public key. */ - PublicKey publicKey = null; - - PBEParameterSpec parameterSpec = null; - SecretKey secretKey = null; - String encryptAlgorithm = "PBEWithMD5AndDES"; - String signatureAlgorithm = "SHAwithDSA"; - String hashAlgorithm = "SHA-512"; - String randomAlgorithm = "SHA1PRNG"; - String encoding = "UTF-8"; - - public JavaEncryptor() { - byte[] salt = ESAPI.securityConfiguration().getMasterSalt(); - char[] pass = ESAPI.securityConfiguration().getMasterPassword(); - - // setup algorithms - encryptAlgorithm = ESAPI.securityConfiguration().getEncryptionAlgorithm(); - signatureAlgorithm = ESAPI.securityConfiguration().getDigitalSignatureAlgorithm(); - randomAlgorithm = ESAPI.securityConfiguration().getRandomAlgorithm(); - hashAlgorithm = ESAPI.securityConfiguration().getHashAlgorithm(); - - try { - // Set up encryption and decryption - parameterSpec = new javax.crypto.spec.PBEParameterSpec(salt, 20); - SecretKeyFactory kf = SecretKeyFactory.getInstance(encryptAlgorithm); - secretKey = kf.generateSecret(new javax.crypto.spec.PBEKeySpec(pass)); - encoding = ESAPI.securityConfiguration().getCharacterEncoding(); - - // Set up signing keypair using the master password and salt - KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA"); - SecureRandom random = SecureRandom.getInstance(randomAlgorithm); - byte[] seed = hash(new String(pass),new String(salt)).getBytes(); - random.setSeed(seed); - keyGen.initialize(1024, random); - KeyPair pair = keyGen.generateKeyPair(); - privateKey = pair.getPrivate(); - publicKey = pair.getPublic(); - } catch (Exception e) { - // can't throw this exception in initializer, but this will log it - new EncryptionException("Encryption failure", "Error creating Encryptor", e); - } - } - - /** - * 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. - * - * @see org.owasp.esapi.Encryptor#hash(java.lang.String,java.lang.String) - */ - public String hash(String plaintext, String salt) throws EncryptionException { - byte[] bytes = null; - try { - MessageDigest digest = MessageDigest.getInstance(hashAlgorithm); - digest.reset(); - digest.update(ESAPI.securityConfiguration().getMasterSalt()); - digest.update(salt.getBytes()); - digest.update(plaintext.getBytes()); - - // rehash a number of times to help strengthen weak passwords - bytes = digest.digest(); - for (int i = 0; i < 1024; i++) { - digest.reset(); - bytes = digest.digest(bytes); - } - String encoded = ESAPI.encoder().encodeForBase64(bytes,false); - return encoded; - } catch (NoSuchAlgorithmException e) { - throw new EncryptionException("Internal error", "Can't find hash algorithm " + hashAlgorithm, e); - } - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IEncryptor#encrypt(java.lang.String) - */ - public String encrypt(String plaintext) throws EncryptionException { - // Note - Cipher is not threadsafe so we create one locally - try { - Cipher encrypter = Cipher.getInstance(encryptAlgorithm); - encrypter.init(Cipher.ENCRYPT_MODE, secretKey, parameterSpec); - byte[] output = plaintext.getBytes(encoding); - byte[] enc = encrypter.doFinal(output); - return ESAPI.encoder().encodeForBase64(enc,false); - } catch (Exception e) { - throw new EncryptionException("Decryption failure", "Decryption problem: " + e.getMessage(), e); - } - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IEncryptor#decrypt(java.lang.String) - */ - public String decrypt(String ciphertext) throws EncryptionException { - // Note - Cipher is not threadsafe so we create one locally - try { - Cipher decrypter = Cipher.getInstance(encryptAlgorithm); - decrypter.init(Cipher.DECRYPT_MODE, secretKey, parameterSpec); - byte[] dec = ESAPI.encoder().decodeFromBase64(ciphertext); - byte[] output = decrypter.doFinal(dec); - return new String(output, encoding); - } catch (Exception e) { - throw new EncryptionException("Decryption failed", "Decryption problem: " + e.getMessage(), e); - } - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IEncryptor#sign(java.lang.String) - */ - public String sign(String data) throws EncryptionException { - String signatureAlgorithm="SHAwithDSA"; - try { - Signature signer = Signature.getInstance(signatureAlgorithm); - signer.initSign(privateKey); - signer.update(data.getBytes()); - byte[] bytes = signer.sign(); - return ESAPI.encoder().encodeForBase64(bytes,true); - } catch (Exception e) { - throw new EncryptionException("Signature failure", "Can't find signature algorithm " + signatureAlgorithm, e); - } - } - - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IEncryptor#verifySignature(java.lang.String, - * java.lang.String) - */ - public boolean verifySignature(String signature, String data) { - try { - byte[] bytes = ESAPI.encoder().decodeFromBase64(signature); - Signature signer = Signature.getInstance(signatureAlgorithm); - signer.initVerify(publicKey); - signer.update(data.getBytes()); - return signer.verify(bytes); - } catch (Exception e) { - new EncryptionException("Invalid signature", "Problem verifying signature: " + e.getMessage(), e); - return false; - } - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IEncryptor#seal(java.lang.String, - * java.lang.String) - */ - public String seal(String data, long expiration) throws IntegrityException { - try { - // mix in some random data so even identical data and timestamp produces different seals - String random = ESAPI.randomizer().getRandomString(10, DefaultEncoder.CHAR_ALPHANUMERICS); - return this.encrypt(expiration + ":" + random + ":" + data); - } catch( EncryptionException e ) { - throw new IntegrityException( e.getUserMessage(), e.getLogMessage(), e ); - } - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IEncryptor#unseal(java.lang.String) - */ - public String unseal(String seal) throws EncryptionException { - - String plaintext = null; - try { - plaintext = decrypt(seal); - } catch (EncryptionException e) { - throw new EncryptionException("Invalid seal", "Seal did not decrypt properly", e); - } - - int index = plaintext.indexOf(":"); - if (index == -1) { - throw new EncryptionException("Invalid seal", "Seal did not contain properly formatted separator"); - } - - String timestring = plaintext.substring(0, index); - long now = new Date().getTime(); - long expiration = Long.parseLong(timestring); - if (now > expiration) { - throw new EncryptionException("Invalid seal", "Seal expiration date has expired"); - } - - index = plaintext.indexOf(":", index+1); - String sealedValue = plaintext.substring(index + 1); - return sealedValue; - } - - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IEncryptor#verifySeal(java.lang.String) - */ - public boolean verifySeal( String seal ) { - try { - unseal( seal ); - return true; - } catch( Exception e ) { - return false; - } - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IEncryptor#getTimeStamp() - */ - public long getTimeStamp() { - return new Date().getTime(); - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IEncryptor#getTimeStamp() - */ - public long getRelativeTimeStamp( long offset ) { - return new Date().getTime() + offset; - } - -} diff --git a/src/org/owasp/esapi/reference/JavaLogFactory.java b/src/org/owasp/esapi/reference/JavaLogFactory.java deleted file mode 100644 index c3dae1be1..000000000 --- a/src/org/owasp/esapi/reference/JavaLogFactory.java +++ /dev/null @@ -1,278 +0,0 @@ -/** - * - */ -package org.owasp.esapi.reference; - -import java.util.logging.Level; - -import javax.servlet.http.HttpSession; - -import org.owasp.esapi.ESAPI; -import org.owasp.esapi.LogFactory; -import org.owasp.esapi.Logger; -import org.owasp.esapi.User; - -/** - * 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. - * - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security - * @since June 1, 2007 - * @see org.owasp.esapi.Logger - */ -public class JavaLogFactory implements LogFactory { - - private String applicationName; - - public JavaLogFactory(String applicationName) { - this.applicationName = applicationName; - } - - /* (non-Javadoc) - * @see org.owasp.esapi.interfaces.ILogFactory#getLogger(java.lang.Class) - */ - public Logger getLogger(Class clazz) { - return new JavaLogger(applicationName, clazz.getName()); - } - - /* (non-Javadoc) - * @see org.owasp.esapi.interfaces.ILogFactory#getLogger(java.lang.String) - */ - public Logger getLogger(String name) { - return new JavaLogger(applicationName, name); - } - - private static class JavaLogger implements org.owasp.esapi.Logger { - - /** The jlogger. */ - private java.util.logging.Logger jlogger = null; - - /** The application name. */ - private String applicationName = null; - - /** The module name. */ - private String moduleName = null; - - /** - * Public constructor should only ever be called via the appropriate LogFactory - * - * @param applicationName the application name - * @param moduleName the module name - */ - public JavaLogger(String applicationName, String moduleName) { - this.applicationName = applicationName; - this.moduleName = moduleName; - this.jlogger = java.util.logging.Logger.getLogger(applicationName + ":" + moduleName); - // Beware getting info from SecurityConfiguration, since it logs. - this.jlogger.setLevel( Level.ALL ); - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.ILogger#logTrace(short, java.lang.String, java.lang.String, java.lang.Throwable) - */ - public void trace(String type, String message, Throwable throwable) { - log(Level.FINEST, type, message, throwable); - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.ILogger#logTrace(java.lang.String, java.lang.String) - */ - public void trace(String type, String message) { - log(Level.FINEST, type, message, null); - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.ILogger#logDebug(short, java.lang.String, java.lang.String, java.lang.Throwable) - */ - public void debug(String type, String message, Throwable throwable) { - log(Level.FINE, type, message, throwable); - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.ILogger#logDebug(java.lang.String, java.lang.String) - */ - public void debug(String type, String message) { - log(Level.FINE, type, message, null); - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.ILogger#logError(short, java.lang.String, java.lang.String, java.lang.Throwable) - */ - public void error(String type, String message, Throwable throwable) { - log(Level.SEVERE, type, message, throwable); - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.ILogger#logError(java.lang.String, java.lang.String) - */ - public void error(String type, String message) { - log(Level.SEVERE, type, message, null); - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.ILogger#logSuccess(short, java.lang.String, java.lang.String, - * java.lang.Throwable) - */ - public void info(String type, String message) { - log(Level.INFO, type, message, null); - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.ILogger#logSuccess(short, java.lang.String, java.lang.String, - * java.lang.Throwable) - */ - public void info(String type, String message, Throwable throwable) { - log(Level.INFO, type, message, throwable); - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.ILogger#logWarning(short, java.lang.String, java.lang.String, - * java.lang.Throwable) - */ - public void warning(String type, String message, Throwable throwable) { - log(Level.WARNING, type, message, throwable); - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.ILogger#logWarning(java.lang.String, java.lang.String) - */ - public void warning(String type, String message) { - log(Level.WARNING, type, message, null); - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.ILogger#logCritical(short, java.lang.String, java.lang.String, - * java.lang.Throwable) - */ - public void fatal(String type, String message, Throwable throwable) { - log(Level.SEVERE, type, message, throwable); - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.ILogger#logCritical(java.lang.String, java.lang.String) - */ - public void fatal(String type, String message) { - log(Level.SEVERE, type, message, null); - } - - /** - * Log the message after optionally encoding any special characters that might inject into an HTML based log viewer. - * - * @param message the message - * @param level the level - * @param type the type - * @param throwable the throwable - */ - private void log(Level level, String type, String message, Throwable throwable) { - User user = ESAPI.authenticator().getCurrentUser(); - - // get a random session number - String counter = "unknown"; - try { - HttpSession session = ESAPI.httpUtilities().getCurrentRequest().getSession(); - counter = (String)session.getAttribute("ESAPI_SESSION" ); - if ( counter == null ) { - counter = ""+ ESAPI.randomizer().getRandomInteger(0, 100000); - session.setAttribute("ESAPI_SESSION", counter); - } - } catch( NullPointerException e ) { - // continue - } - - // ensure there's something to log - if ( message == null ) { - message = ""; - } - - // ensure no CRLF injection into logs for forging records - String clean = message.replace( '\n', '_' ).replace( '\r', '_' ); - if ( ((DefaultSecurityConfiguration)ESAPI.securityConfiguration()).getLogEncodingRequired() ) { - clean = ESAPI.encoder().encodeForHTML(message); - if (!message.equals(clean)) { - clean += " (Encoded)"; - } - } - if ( throwable != null ) { - String fqn = throwable.getClass().getName(); - int index = fqn.lastIndexOf('.'); - if ( index > 0 ) fqn = fqn.substring(index + 1); - StackTraceElement ste = throwable.getStackTrace()[0]; - clean += "\n " + fqn + " @ " + ste.getClassName() + "." + ste.getMethodName() + "(" + ste.getFileName() + ":" + ste.getLineNumber() + ")"; - } - String msg = ""; - if ( user != null ) { - msg = type + ": " + user.getAccountName() + "("+ counter +")(" + user.getLastHostAddress() + ") -- " + clean; - } - - // jlogger.logp(level, applicationName, moduleName, msg, throwable); - jlogger.logp(level, applicationName, moduleName, msg); - } - - /* (non-Javadoc) - * @see org.owasp.esapi.interfaces.ILogger#isDebugEnabled() - */ - public boolean isDebugEnabled() { - return jlogger.isLoggable(Level.FINE); - } - - /* (non-Javadoc) - * @see org.owasp.esapi.interfaces.ILogger#isErrorEnabled() - */ - public boolean isErrorEnabled() { - return jlogger.isLoggable(Level.SEVERE); - } - - /* (non-Javadoc) - * @see org.owasp.esapi.interfaces.ILogger#isFatalEnabled() - */ - public boolean isFatalEnabled() { - return jlogger.isLoggable(Level.SEVERE); - } - - /* (non-Javadoc) - * @see org.owasp.esapi.interfaces.ILogger#isInfoEnabled() - */ - public boolean isInfoEnabled() { - return jlogger.isLoggable(Level.INFO); - } - - /* (non-Javadoc) - * @see org.owasp.esapi.interfaces.ILogger#isTraceEnabled() - */ - public boolean isTraceEnabled() { - return jlogger.isLoggable(Level.FINEST); - } - - /* (non-Javadoc) - * @see org.owasp.esapi.interfaces.ILogger#isWarningEnabled() - */ - public boolean isWarningEnabled() { - return jlogger.isLoggable(Level.WARNING); - } - - } -} diff --git a/src/org/owasp/esapi/reference/RandomAccessReferenceMap.java b/src/org/owasp/esapi/reference/RandomAccessReferenceMap.java deleted file mode 100644 index 98f7d7200..000000000 --- a/src/org/owasp/esapi/reference/RandomAccessReferenceMap.java +++ /dev/null @@ -1,166 +0,0 @@ -/** - * 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.reference; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Set; -import java.util.TreeSet; - -import org.owasp.esapi.AccessReferenceMap; -import org.owasp.esapi.ESAPI; -import org.owasp.esapi.Randomizer; -import org.owasp.esapi.errors.AccessControlException; - -/** - * 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. - * - * @author Jeff Williams (jeff.williams@aspectsecurity.com) - * @since June 1, 2007 - * @see org.owasp.esapi.AccessReferenceMap - */ -public class RandomAccessReferenceMap implements AccessReferenceMap { - - /** The itod (indirect to direct) */ - HashMap itod = new HashMap(); - - /** The dtoi (direct to indirect) */ - HashMap dtoi = new HashMap(); - - /** The random. */ - Randomizer random = ESAPI.randomizer(); - - /** - * This AccessReferenceMap implementation uses short random strings to - * create a layer of indirection. Other possible implementations would use - * simple integers as indirect references. - */ - public RandomAccessReferenceMap() { - // call update to set up the references - } - - /** - * Instantiates a new access reference map. - * - * @param directReferences - * the direct references - */ - public RandomAccessReferenceMap(Set directReferences) { - update(directReferences); - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.AccessReferenceMap#iterator() - */ - public Iterator iterator() { - TreeSet sorted = new TreeSet(dtoi.keySet()); - return sorted.iterator(); - } - - /** - * Adds a direct reference and a new random indirect reference, overwriting any existing values. - * @param direct - */ - public String addDirectReference(Object direct) { - if ( dtoi.keySet().contains( direct ) ) { - return (String)dtoi.get( direct ); - } - String indirect = getUniqueRandomReference(); - itod.put(indirect, direct); - dtoi.put(direct, indirect); - return indirect; - } - - private String getUniqueRandomReference() { - String candidate = null; - do { - candidate = random.getRandomString(6, DefaultEncoder.CHAR_ALPHANUMERICS); - } while (itod.keySet().contains(candidate)); - return candidate; - } - - /** - * Remove a direct reference and the corresponding indirect reference. - * @param direct - */ - public String removeDirectReference(Object direct) throws AccessControlException { - String indirect = (String)dtoi.get(direct); - if ( indirect != null ) { - itod.remove(indirect); - dtoi.remove(direct); - } - return indirect; - } - - /** - * 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. - * - * @param directReferences - * the direct references - */ - final public void update(Set directReferences) { - HashMap dtoi_old = (HashMap) dtoi.clone(); - dtoi.clear(); - itod.clear(); - - Iterator i = directReferences.iterator(); - while (i.hasNext()) { - Object direct = i.next(); - - // get the old indirect reference - String indirect = (String) dtoi_old.get(direct); - - // if the old reference is null, then create a new one that doesn't - // collide with any existing indirect references - if (indirect == null) { - indirect = getUniqueRandomReference(); - } - itod.put(indirect, direct); - dtoi.put(direct, indirect); - } - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IAccessReferenceMap#getIndirectReference(java.lang.String) - */ - public String getIndirectReference(Object directReference) { - return (String) dtoi.get(directReference); - } - - /* - * (non-Javadoc) - * - * @see org.owasp.esapi.interfaces.IAccessReferenceMap#getDirectReference(java.lang.String) - */ - public Object getDirectReference(String indirectReference) throws AccessControlException { - if (itod.containsKey(indirectReference)) { - return itod.get(indirectReference); - } - throw new AccessControlException("Access denied", "Request for invalid indirect reference: " + indirectReference); - } -} diff --git a/src/org/owasp/esapi/reference/package.html b/src/org/owasp/esapi/reference/package.html deleted file mode 100644 index 0e110cb91..000000000 --- a/src/org/owasp/esapi/reference/package.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - -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. - - - diff --git a/src/org/owasp/esapi/tags/EncodeForHTMLAttributeTag.java b/src/org/owasp/esapi/tags/EncodeForHTMLAttributeTag.java deleted file mode 100644 index 05f68efce..000000000 --- a/src/org/owasp/esapi/tags/EncodeForHTMLAttributeTag.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.owasp.esapi.tags; - -import java.io.IOException; - -import javax.servlet.jsp.JspTagException; -import javax.servlet.jsp.JspWriter; -import javax.servlet.jsp.tagext.BodyContent; -import javax.servlet.jsp.tagext.BodyTag; -import javax.servlet.jsp.tagext.BodyTagSupport; - -import org.owasp.esapi.ESAPI; -import org.owasp.esapi.Encoder; - -public class EncodeForHTMLAttributeTag extends BodyTagSupport { - - /** - * - */ - private static final long serialVersionUID = 1L; - private String name; - - public EncodeForHTMLAttributeTag() {} - - - - public int doStartTag() { - - //return EVAL_BODY_TAG; <-- Deprecated - return BodyTag.EVAL_BODY_BUFFERED; - } - - - public int doAfterBody() throws JspTagException { - - - try { - - BodyContent body = getBodyContent(); - - String content = body.getString(); - JspWriter out = body.getEnclosingWriter(); - - Encoder e = ESAPI.encoder(); - - out.println( e.encodeForHTMLAttribute(content) ); - body.clearBody(); - - return EVAL_PAGE; - - } catch (IOException ioe) { - throw new JspTagException("error in encodeForHTML tag doAfterBody()",ioe); - } - - } - - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - -} diff --git a/src/org/owasp/esapi/tags/EncodeForHTMLJavaScriptTag.java b/src/org/owasp/esapi/tags/EncodeForHTMLJavaScriptTag.java deleted file mode 100644 index b24e0fcf3..000000000 --- a/src/org/owasp/esapi/tags/EncodeForHTMLJavaScriptTag.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.owasp.esapi.tags; - -import java.io.IOException; - -import javax.servlet.jsp.JspTagException; -import javax.servlet.jsp.JspWriter; -import javax.servlet.jsp.tagext.BodyContent; -import javax.servlet.jsp.tagext.BodyTag; -import javax.servlet.jsp.tagext.BodyTagSupport; - -import org.owasp.esapi.ESAPI; -import org.owasp.esapi.Encoder; - -public class EncodeForHTMLJavaScriptTag extends BodyTagSupport { - - /** - * - */ - private static final long serialVersionUID = 1L; - private String name; - - public EncodeForHTMLJavaScriptTag() {} - - - - public int doStartTag() { - - //return EVAL_BODY_TAG; <-- Deprecated - return BodyTag.EVAL_BODY_BUFFERED; - } - - - public int doAfterBody() throws JspTagException { - - - try { - - BodyContent body = getBodyContent(); - - String content = body.getString(); - JspWriter out = body.getEnclosingWriter(); - - Encoder e = ESAPI.encoder(); - - out.println( e.encodeForJavaScript(content) ); - body.clearBody(); - - return EVAL_PAGE; - - } catch (IOException ioe) { - throw new JspTagException("error in encodeForHTML tag doAfterBody()",ioe); - } - - } - - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - -} diff --git a/src/org/owasp/esapi/tags/EncodeForHTMLTag.java b/src/org/owasp/esapi/tags/EncodeForHTMLTag.java deleted file mode 100644 index 97585453c..000000000 --- a/src/org/owasp/esapi/tags/EncodeForHTMLTag.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.owasp.esapi.tags; - -import java.io.IOException; - -import javax.servlet.jsp.JspTagException; -import javax.servlet.jsp.JspWriter; -import javax.servlet.jsp.tagext.BodyContent; -import javax.servlet.jsp.tagext.BodyTag; -import javax.servlet.jsp.tagext.BodyTagSupport; - -import org.owasp.esapi.ESAPI; -import org.owasp.esapi.Encoder; - -public class EncodeForHTMLTag extends BodyTagSupport { - - /** - * - */ - private static final long serialVersionUID = 1L; - private String name; - - public EncodeForHTMLTag() {} - - - public int doStartTag() { - - //return EVAL_BODY_TAG; <-- Deprecated - return BodyTag.EVAL_BODY_BUFFERED; - } - - - public int doAfterBody() throws JspTagException { - - - try { - - BodyContent body = getBodyContent(); - - String content = body.getString(); - JspWriter out = body.getEnclosingWriter(); - - Encoder e = ESAPI.encoder(); - - out.println( e.encodeForHTML(content) ); - body.clearBody(); - - return EVAL_PAGE; - - } catch (IOException ioe) { - throw new JspTagException("error in encodeForHTML tag doAfterBody()",ioe); - } - - } - - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - -} diff --git a/src/org/owasp/esapi/tags/EncodeForVBScriptTag.java b/src/org/owasp/esapi/tags/EncodeForVBScriptTag.java deleted file mode 100644 index 812f20f58..000000000 --- a/src/org/owasp/esapi/tags/EncodeForVBScriptTag.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.owasp.esapi.tags; - -import java.io.IOException; - -import javax.servlet.jsp.JspTagException; -import javax.servlet.jsp.JspWriter; -import javax.servlet.jsp.tagext.BodyContent; -import javax.servlet.jsp.tagext.BodyTag; -import javax.servlet.jsp.tagext.BodyTagSupport; - -import org.owasp.esapi.ESAPI; -import org.owasp.esapi.Encoder; - -public class EncodeForVBScriptTag extends BodyTagSupport { - - /** - * - */ - private static final long serialVersionUID = 1L; - private String name; - - public EncodeForVBScriptTag() {} - - - public int doStartTag() { - - //return EVAL_BODY_TAG; <-- Deprecated - return BodyTag.EVAL_BODY_BUFFERED; - - } - - public int doEndTag() { - - return SKIP_BODY; - - } - - public int doAfterBody() throws JspTagException { - - - BodyContent body = getBodyContent(); - - String content = body.getString(); - JspWriter out = body.getEnclosingWriter(); - - Encoder e = ESAPI.encoder(); - - try { - - out.println( e.encodeForVBScript(content) ); - body.clearBody(); - - } catch (IOException ioe) { - throw new JspTagException("error in encodeForHTML tag doAfterBody()",ioe); - } - - return SKIP_BODY; - - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - -} diff --git a/src/site/resources/images/owasp.png b/src/site/resources/images/owasp.png new file mode 100644 index 000000000..90fb9d2ce Binary files /dev/null and b/src/site/resources/images/owasp.png differ diff --git a/src/site/site.xml b/src/site/site.xml new file mode 100644 index 000000000..692d5b637 --- /dev/null +++ b/src/site/site.xml @@ -0,0 +1,27 @@ + + + + /images/owasp.png + https://owasp.org/www-project-enterprise-security-api/ + + + org.apache.maven.skins + maven-fluido-skin + ${version.fluido} + + + + false + true + + + + + + +

+ + + diff --git a/src/test/java/org/owasp/esapi/ESAPIContractAPITest.java b/src/test/java/org/owasp/esapi/ESAPIContractAPITest.java new file mode 100644 index 000000000..059eb00aa --- /dev/null +++ b/src/test/java/org/owasp/esapi/ESAPIContractAPITest.java @@ -0,0 +1,52 @@ +package org.owasp.esapi; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentMatchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.internal.verification.VerificationModeFactory; +import org.owasp.esapi.util.ObjFactory; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ObjFactory.class}) +public class ESAPIContractAPITest { + + @Mock + private SecurityConfiguration mockSecConfig; + + @Mock + private Validator mockValidator; + + @Before + public void configureStaticContexts() throws Exception { + PowerMockito.mockStatic(ObjFactory.class); + PowerMockito.when(ObjFactory.class, "make", ArgumentMatchers.anyString(), ArgumentMatchers.eq("SecurityConfiguration")).thenReturn(mockSecConfig); + PowerMockito.when(ObjFactory.class, "make", ArgumentMatchers.eq("MOCK_TEST_VALIDATOR"), ArgumentMatchers.eq("Validator")).thenReturn(mockValidator); + + PowerMockito.when(mockSecConfig.getValidationImplementation()).thenReturn("MOCK_TEST_VALIDATOR"); + } + + @Test + public void testValidatorFromConfiguration() { + Validator validator = ESAPI.validator(); + Assert.assertEquals("ESAPI Configuration should return Validator as specified by the SecurityConfiguration", mockValidator, validator); + + PowerMockito.verifyStatic(ObjFactory.class, VerificationModeFactory.times(1)); + ObjFactory.make(ArgumentMatchers.anyString(), ArgumentMatchers.eq("SecurityConfiguration")); + + PowerMockito.verifyStatic(ObjFactory.class, VerificationModeFactory.times(1)); + ObjFactory.make(ArgumentMatchers.eq("MOCK_TEST_VALIDATOR"), ArgumentMatchers.eq("Validator")); + + PowerMockito.verifyNoMoreInteractions(ObjFactory.class); + + Mockito.verify(mockSecConfig, Mockito.times(1)).getValidationImplementation(); + } + +} diff --git a/src/test/java/org/owasp/esapi/ESAPIVerifyAllowedMethods.java b/src/test/java/org/owasp/esapi/ESAPIVerifyAllowedMethods.java new file mode 100644 index 000000000..751a95d52 --- /dev/null +++ b/src/test/java/org/owasp/esapi/ESAPIVerifyAllowedMethods.java @@ -0,0 +1,68 @@ +package org.owasp.esapi; + +import org.bouncycastle.crypto.modes.CBCModeCipher; +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; +import org.owasp.esapi.errors.ConfigurationException; + + +public class ESAPIVerifyAllowedMethods { + + @Test (expected = IllegalArgumentException.class) + public void verifyNulParamThrows() { + ESAPI.isMethodExplicityEnabled(null); + } + + @Test (expected = IllegalArgumentException.class) + public void verifyEmptyNoWhitespaceParameterThrows() { + ESAPI.isMethodExplicityEnabled(""); + } + + @Test (expected = IllegalArgumentException.class) + public void verifyEmptyOnlyWhitespaceParameterThrows() { + ESAPI.isMethodExplicityEnabled(" "); + } + + @Test (expected = IllegalArgumentException.class) + public void verifyEmptyOnlyTabWhitespaceParameterThrows() { + ESAPI.isMethodExplicityEnabled("\t"); + } + + @Test (expected = IllegalArgumentException.class) + public void verifyEmptyOnlyNewlineWhitespaceParameterThrows() { + ESAPI.isMethodExplicityEnabled("\n"); + } + + + + @Test (expected = IllegalArgumentException.class) + public void verifyNonEsapiPackageParameterThrows() { + ESAPI.isMethodExplicityEnabled("com.myPackage.myScope.method"); + } + @Test + public void verifyUnknownMethodFailsEnableCheck() { + Assert.assertFalse(ESAPI.isMethodExplicityEnabled("org.owasp.esapi.reference.DefaultEncoder.encodeForSQ")); + } + + @Test + public void verifyDefinedRestrictionIsCaught() { + Assert.assertTrue(ESAPI.isMethodExplicityEnabled("org.owasp.esapi.reference.DefaultEncoder.encodeForSQL")); + } + + @Test + public void testMissingPropertyReturnsFalse() { + try { + SecurityConfiguration mockConfig = Mockito.mock(SecurityConfiguration.class); + Mockito.when(mockConfig.getStringProp("ESAPI.dangerouslyAllowUnsafeMethods.methodNames")).thenThrow(ConfigurationException.class); + ESAPI.override(mockConfig); + + Assert.assertFalse(ESAPI.isMethodExplicityEnabled("org.owasp.esapi.thisValueDoesNotMatter")); + Mockito.verify(mockConfig, Mockito.times(1)).getStringProp("ESAPI.dangerouslyAllowUnsafeMethods.methodNames"); + } finally { + ESAPI.override(null); + } + + } + +} diff --git a/src/test/java/org/owasp/esapi/PreparedStringTest.java b/src/test/java/org/owasp/esapi/PreparedStringTest.java new file mode 100644 index 000000000..c3ddf8ece --- /dev/null +++ b/src/test/java/org/owasp/esapi/PreparedStringTest.java @@ -0,0 +1,66 @@ +/** + * 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 2009 + */ + +package org.owasp.esapi; + +import junit.framework.TestCase; + +import org.owasp.esapi.codecs.Codec; +import org.owasp.esapi.codecs.HTMLEntityCodec; + +public class PreparedStringTest extends TestCase { + + private final static Codec htmlEntityCodec = new HTMLEntityCodec(); + + public void testPreparedString() { + PreparedString ps1 = new PreparedString( "Test ? is ?", htmlEntityCodec ); + ps1.set( 1, "[]<>;\"\'PreparedString" ); + ps1.set( 2, "cool" ); + try { + PreparedString ps2 = new PreparedString( "Test ? is ?", htmlEntityCodec ); + ps2.set( 2, "cool" ); + } catch( Exception e ) { + fail(e.getMessage()); + } + + try { + PreparedString ps3 = new PreparedString( "Test ? is ?", htmlEntityCodec ); + ps3.set( 1, "[]<>;\"\'PreparedString" ); + ps3.set( 2, "cool" ); + ps3.set( 3, "cool" ); + fail("Was able to set parameters past the end of the parameter stack."); + } catch( Exception e ) { + // Success + } + + try { + PreparedString ps4 = new PreparedString( "???", htmlEntityCodec ); + ps4.set( 1, "1" ); + ps4.set( 2, "2" ); + ps4.set( 3, "3" ); + } catch( Exception e ) { + fail(e.getMessage()); + } + + try { + PreparedString ps5 = new PreparedString( "??x", htmlEntityCodec ); + ps5.set( 1, "1" ); + ps5.set( 2, "2" ); + } catch( Exception e ) { + fail(e.getMessage()); + } + } +} diff --git a/src/test/java/org/owasp/esapi/SecurityConfigurationWrapper.java b/src/test/java/org/owasp/esapi/SecurityConfigurationWrapper.java new file mode 100644 index 000000000..1d5a521b8 --- /dev/null +++ b/src/test/java/org/owasp/esapi/SecurityConfigurationWrapper.java @@ -0,0 +1,620 @@ +package org.owasp.esapi; + +import org.owasp.esapi.errors.ConfigurationException; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import java.util.regex.Pattern; + +/** + * Simple wrapper implementation of {@link SecurityConfiguration}. + * This allows for easy subclassing and property fixups for unit tests. + * + * Note that there are some compilers have issues with Override + * attributes on methods implementing a interface method with some + * compilers. Technically Override on such methods is a 1.6 feature so + * they are commented out here. + */ +public class SecurityConfigurationWrapper implements SecurityConfiguration +{ + private SecurityConfiguration wrapped; + + /** + * Constructor wrapping the given configuration. + * @param wrapped The configuration to wrap. + */ + public SecurityConfigurationWrapper(SecurityConfiguration wrapped) + { + this.wrapped = wrapped; + } + + /** + * Access the wrapped configuration. + * @return The wrapped configuration. + */ + public SecurityConfiguration getWrappedSecurityConfiguration() + { + return wrapped; + } + + /** + * {@inheritDoc} + */ + // @Override + public String getApplicationName() + { + return wrapped.getApplicationName(); + } + + /** + * {@inheritDoc} + */ + // @Override + public String getLogImplementation() + { + return wrapped.getLogImplementation(); + } + + /** + * {@inheritDoc} + */ + // @Override + public String getAuthenticationImplementation() + { + return wrapped.getAuthenticationImplementation(); + } + + /** + * {@inheritDoc} + */ + // @Override + public String getEncoderImplementation() + { + return wrapped.getEncoderImplementation(); + } + + /** + * {@inheritDoc} + */ + // @Override + public String getAccessControlImplementation() + { + return wrapped.getAccessControlImplementation(); + } + + /** + * {@inheritDoc} + */ + // @Override + public String getIntrusionDetectionImplementation() + { + return wrapped.getIntrusionDetectionImplementation(); + } + + /** + * {@inheritDoc} + */ + // @Override + public String getRandomizerImplementation() + { + return wrapped.getRandomizerImplementation(); + } + + /** + * {@inheritDoc} + */ + // @Override + public String getEncryptionImplementation() + { + return wrapped.getEncryptionImplementation(); + } + + /** + * {@inheritDoc} + */ + // @Override + public String getValidationImplementation() + { + return wrapped.getValidationImplementation(); + } + + /** + * {@inheritDoc} + */ + // @Override + public Pattern getValidationPattern( String typeName ) + { + return wrapped.getValidationPattern(typeName); + } + + /** + * {@inheritDoc} + */ + // @Override + public String getExecutorImplementation() + { + return wrapped.getExecutorImplementation(); + } + + /** + * {@inheritDoc} + */ + // @Override + public String getHTTPUtilitiesImplementation() + { + return wrapped.getHTTPUtilitiesImplementation(); + } + + /** + * {@inheritDoc} + */ + // @Override + public byte[] getMasterKey() + { + return wrapped.getMasterKey(); + } + + /** + * {@inheritDoc} + */ + // @Override + public File getUploadDirectory() + { + return wrapped.getUploadDirectory(); + } + + /** + * {@inheritDoc} + */ + // @Override + public File getUploadTempDirectory() + { + return wrapped.getUploadTempDirectory(); + } + + /** + * {@inheritDoc} + */ + // @Override + public int getEncryptionKeyLength() + { + return wrapped.getEncryptionKeyLength(); + } + + /** + * {@inheritDoc} + */ + // @Override + public byte[] getMasterSalt() + { + return wrapped.getMasterSalt(); + } + + /** + * {@inheritDoc} + */ + // @Override + public List getAllowedExecutables() + { + return wrapped.getAllowedExecutables(); + } + + /** + * {@inheritDoc} + */ + // @Override + public List getAllowedFileExtensions() + { + return wrapped.getAllowedFileExtensions(); + } + + /** + * {@inheritDoc} + */ + // @Override + public int getAllowedFileUploadSize() + { + return wrapped.getAllowedFileUploadSize(); + } + + /** + * {@inheritDoc} + */ + // @Override + public String getPasswordParameterName() + { + return wrapped.getPasswordParameterName(); + } + + /** + * {@inheritDoc} + */ + // @Override + public String getUsernameParameterName() + { + return wrapped.getUsernameParameterName(); + } + + /** + * {@inheritDoc} + */ + // @Override + public String getEncryptionAlgorithm() + { + return wrapped.getEncryptionAlgorithm(); + } + + /** + * {@inheritDoc} + */ + // @Override + public String getCipherTransformation() + { + return wrapped.getCipherTransformation(); + } + + /** + * {@inheritDoc} + */ + // @Override + public String setCipherTransformation(String cipherXform) + { + return wrapped.setCipherTransformation(cipherXform); + } + + /** + * {@inheritDoc} + */ + // @Override + public boolean useMACforCipherText() + { + return wrapped.useMACforCipherText(); + } + + /** + * {@inheritDoc} + */ + // @Override + public boolean overwritePlainText() + { + return wrapped.overwritePlainText(); + } + + /** + * {@inheritDoc} + */ + // @Override + public String getIVType() + { + return wrapped.getIVType(); + } + + + /** + * {@inheritDoc} + */ + // @Override + public String getHashAlgorithm() + { + return wrapped.getHashAlgorithm(); + } + + /** + * {@inheritDoc} + */ + // @Override + public int getHashIterations() + { + return wrapped.getHashIterations(); + } + + /** + * {@inheritDoc} + */ + // @Override + public String getCharacterEncoding() + { + return wrapped.getCharacterEncoding(); + } + + /** + * {@inheritDoc} + */ + // @Override + public boolean getAllowMultipleEncoding() + { + return wrapped.getAllowMultipleEncoding(); + } + + /** + * {@inheritDoc} + */ + // @Override + public boolean getAllowMixedEncoding() + { + return wrapped.getAllowMixedEncoding(); + } + + /** + * {@inheritDoc} + */ + // @Override + public List getDefaultCanonicalizationCodecs() + { + return wrapped.getDefaultCanonicalizationCodecs(); + } + + /** + * {@inheritDoc} + */ + // @Override + public String getDigitalSignatureAlgorithm() + { + return wrapped.getDigitalSignatureAlgorithm(); + } + + /** + * {@inheritDoc} + */ + // @Override + public int getDigitalSignatureKeyLength() + { + return wrapped.getDigitalSignatureKeyLength(); + } + + /** + * {@inheritDoc} + */ + // @Override + public String getRandomAlgorithm() + { + return wrapped.getRandomAlgorithm(); + } + + /** + * {@inheritDoc} + */ + // @Override + public int getAllowedLoginAttempts() + { + return wrapped.getAllowedLoginAttempts(); + } + + /** + * {@inheritDoc} + */ + // @Override + public int getMaxOldPasswordHashes() + { + return wrapped.getMaxOldPasswordHashes(); + } + + /** + * {@inheritDoc} + */ + // @Override + public Threshold getQuota(String eventName) + { + return wrapped.getQuota(eventName); + } + + /** + * {@inheritDoc} + */ + // @Override + public File getResourceFile( String filename ) + { + return wrapped.getResourceFile(filename); + } + + /** + * {@inheritDoc} + */ + // @Override + public boolean getForceHttpOnlySession() + { + return wrapped.getForceHttpOnlySession(); + } + + /** + * {@inheritDoc} + */ + // @Override + public boolean getForceSecureSession() + { + return wrapped.getForceSecureSession(); + } + + /** + * {@inheritDoc} + */ + // @Override + public boolean getForceHttpOnlyCookies() + { + return wrapped.getForceHttpOnlyCookies(); + } + + /** + * {@inheritDoc} + */ + // @Override + public boolean getForceSecureCookies() + { + return wrapped.getForceSecureCookies(); + } + + /** + * {@inheritDoc} + */ + // @Override + public int getMaxHttpHeaderSize() { + return wrapped.getMaxHttpHeaderSize(); + } + + /** + * {@inheritDoc} + */ + // @Override + public InputStream getResourceStream( String filename ) throws IOException + { + return wrapped.getResourceStream(filename); + } + + + /** + * {@inheritDoc} + */ + // @Override + public void setResourceDirectory(String dir) + { + wrapped.setResourceDirectory(dir); + } + + /** + * {@inheritDoc} + */ + // @Override + public String getResponseContentType() + { + return wrapped.getResponseContentType(); + } + + /** + * {@inheritDoc} + */ + // @Override + public String getHttpSessionIdName() { + return wrapped.getHttpSessionIdName(); + } + + /** + * {@inheritDoc} + */ + // @Override + public long getRememberTokenDuration() + { + return wrapped.getRememberTokenDuration(); + } + + /** + * {@inheritDoc} + */ + // @Override + public int getSessionIdleTimeoutLength() + { + return wrapped.getSessionIdleTimeoutLength(); + } + + /** + * {@inheritDoc} + */ + // @Override + public int getSessionAbsoluteTimeoutLength() + { + return wrapped.getSessionAbsoluteTimeoutLength(); + } + + /** + * {@inheritDoc} + */ + // @Override + public boolean getLogEncodingRequired() + { + return wrapped.getLogEncodingRequired(); + } + + /** + * {@inheritDoc} + */ + // @Override + public boolean getLogApplicationName() + { + return wrapped.getLogApplicationName(); + } + + /** + * {@inheritDoc} + */ + // @Override + public boolean getLogServerIP() + { + return wrapped.getLogServerIP(); + } + + @Override + public int getIntProp(String propertyName) throws ConfigurationException { + return wrapped.getIntProp(propertyName); + } + + @Override + public byte[] getByteArrayProp(String propertyName) throws ConfigurationException { + return wrapped.getByteArrayProp(propertyName); + } + + @Override + public Boolean getBooleanProp(String propertyName) throws ConfigurationException { + return wrapped.getBooleanProp(propertyName); + } + + @Override + public String getStringProp(String propertyName) throws ConfigurationException { + return wrapped.getStringProp(propertyName); + } + + /** + * {@inheritDoc} + */ + // @Override + public File getWorkingDirectory() + { + return wrapped.getWorkingDirectory(); + } + + /** + * {@inheritDoc} + */ + // @Override + public List getAdditionalAllowedCipherModes() { + return wrapped.getAdditionalAllowedCipherModes(); + } + + /** + * {@inheritDoc} + */ + // @Override + public List getCombinedCipherModes() { + return wrapped.getCombinedCipherModes(); + } + + /** + * {@inheritDoc} + */ + public String getPreferredJCEProvider() { + return wrapped.getPreferredJCEProvider(); + } + + /** + * {@inheritDoc} + */ + // @Override + public boolean getDisableIntrusionDetection() { + return wrapped.getDisableIntrusionDetection(); + } + + /** + * {@inheritDoc} + */ + // @Override + public String getKDFPseudoRandomFunction() { + return wrapped.getKDFPseudoRandomFunction(); + } + + /** + * {@inheritDoc} + */ + public boolean getLenientDatesAccepted() { + return wrapped.getLenientDatesAccepted(); + } +} diff --git a/src/test/java/org/owasp/esapi/StringUtilitiesTest.java b/src/test/java/org/owasp/esapi/StringUtilitiesTest.java new file mode 100644 index 000000000..c7f29d27a --- /dev/null +++ b/src/test/java/org/owasp/esapi/StringUtilitiesTest.java @@ -0,0 +1,90 @@ +package org.owasp.esapi; + +import java.util.Arrays; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; +import org.owasp.esapi.StringUtilities; + +public class StringUtilitiesTest extends TestCase { + + /** + * Run all the test cases in this suite. + * This is to allow running from {@code org.owasp.esapi.AllTests}. + * + * @return the test + */ + public static Test suite() { + TestSuite suite = new TestSuite(StringUtilitiesTest.class); + return suite; + } + + /** Test the getLevenshteinDistance() method. */ + public void testGetLevenshteinDistance() { + String src = "GUMBO"; + String target = "GAMBOL"; + assertTrue( 2 == StringUtilities.getLevenshteinDistance(src, target) ); + assertTrue( 2 == StringUtilities.getLevenshteinDistance(target, src) ); + assertTrue( 0 == StringUtilities.getLevenshteinDistance(src, src) ); + assertTrue( 5 == StringUtilities.getLevenshteinDistance(src, "") ); + assertTrue( 6 == StringUtilities.getLevenshteinDistance("", target) ); + + try { + @SuppressWarnings("unused") + int ldist = StringUtilities.getLevenshteinDistance(null, "abc"); + } catch ( IllegalArgumentException ex ) { + assertTrue( ex.getClass().getName().equals( IllegalArgumentException.class.getName() )); + } + + try { + @SuppressWarnings("unused") + int ldist = StringUtilities.getLevenshteinDistance("abc", null); + } catch ( IllegalArgumentException ex ) { + assertTrue( ex.getClass().getName().equals( IllegalArgumentException.class.getName() )); + } + } + + /** Test the union() method. */ + public void testUnion() { + char[] a1 = { 'a', 'b', 'c' }; + char[] a2 = { 'c', 'd', 'e' }; + char[] union = StringUtilities.union(a1, a2); + assertTrue( Arrays.equals( union, new char[] {'a','b','c','d','e' } ) ); + } + + /** Test the contains() method. */ + public void contains() { + StringBuilder sb = new StringBuilder( "abc" ); + assertTrue( StringUtilities.contains(sb, 'b') ); + assertFalse( StringUtilities.contains(sb, 'x') ); + } + + /** Test the notNullOrEmpty() method. */ + public void testNotNullOrEmpty() { + String str = "A string"; + assertTrue( StringUtilities.notNullOrEmpty(str, false) ); + assertTrue( StringUtilities.notNullOrEmpty(str, true) ); + str = " A string "; + assertTrue( StringUtilities.notNullOrEmpty(str, false) ); + assertTrue( StringUtilities.notNullOrEmpty(str, true) ); + str = " "; + assertTrue( StringUtilities.notNullOrEmpty(str, false) ); + assertFalse( StringUtilities.notNullOrEmpty(str, true) ); + str = ""; + assertFalse( StringUtilities.notNullOrEmpty(str, false) ); + assertFalse( StringUtilities.notNullOrEmpty(str, true) ); + str = null; + assertFalse( StringUtilities.notNullOrEmpty(str, false) ); + assertFalse( StringUtilities.notNullOrEmpty(str, true) ); + } + + public void testReplaceNull() { + assertEquals( "TEST", StringUtilities.replaceNull( "TEST", "ABCD" ) ); + assertEquals( "REPLACED", StringUtilities.replaceNull( "NULL", "REPLACED" ) ); + assertEquals( "Replaced", StringUtilities.replaceNull( null, "Replaced" ) ); + assertEquals( "Replaced", StringUtilities.replaceNull( " ", "Replaced" ) ); + assertEquals( " Test ", StringUtilities.replaceNull( " Test ", "Replaced" ) ); + assertEquals( "Replaced", StringUtilities.replaceNull( " NULL ", "Replaced" ) ); + } +} diff --git a/src/test/java/org/owasp/esapi/UserTest.java b/src/test/java/org/owasp/esapi/UserTest.java new file mode 100644 index 000000000..109a6251a --- /dev/null +++ b/src/test/java/org/owasp/esapi/UserTest.java @@ -0,0 +1,106 @@ +/** + * 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 junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * @author Jeff Williams (jeff.williams@aspectsecurity.com) + */ +public class UserTest extends TestCase { + + public UserTest(String testName) { + super(testName); + } + + protected void setUp() throws Exception { + // none + } + + protected void tearDown() throws Exception { + // none + } + + public static Test suite() { + TestSuite suite = new TestSuite(UserTest.class); + return suite; + } + + public void testAllMethods() throws Exception { + // create a user to test Anonymous + String accountName = ESAPI.randomizer().getRandomString(8, EncoderConstants.CHAR_ALPHANUMERICS); + Authenticator instance = ESAPI.authenticator(); + String password = instance.generateStrongPassword(); + + // Probably could skip the assignment here, but maybe someone had + // future plans to use this. So will just suppress warning for now. + @SuppressWarnings("unused") + User user = instance.createUser(accountName, password, password); + + // test the rest of the Anonymous user + try { User.ANONYMOUS.addRole(null); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.addRoles(null); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.changePassword(null, null, null); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.disable(); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.enable(); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.getAccountId(); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.getAccountName(); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.getName(); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.getCSRFToken(); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.getExpirationTime(); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.getFailedLoginCount(); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.getLastFailedLoginTime(); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.getLastLoginTime(); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.getLastPasswordChangeTime(); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.getRoles(); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.getScreenName(); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.addSession(null); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.removeSession(null); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.incrementFailedLoginCount(); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.isAnonymous(); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.isEnabled(); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.isExpired(); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.isInRole(null); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.isLocked(); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.isLoggedIn(); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.isSessionAbsoluteTimeout(); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.isSessionTimeout(); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.lock(); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.loginWithPassword(null); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.logout(); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.removeRole(null); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.resetCSRFToken(); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.setAccountName(null); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.setExpirationTime(null); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.setRoles(null); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.setScreenName(null); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.unlock(); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.verifyPassword(null); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.setLastFailedLoginTime(null); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.setLastLoginTime(null); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.setLastHostAddress(null); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.setLastPasswordChangeTime(null); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.getEventMap(); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.getLocale(); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.setLocale(null); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.getAccountName(); } catch( RuntimeException e ) {} + try { User.ANONYMOUS.getAccountName(); } catch( RuntimeException e ) {} + } +} + + diff --git a/src/test/java/org/owasp/esapi/ValidationErrorListTest.java b/src/test/java/org/owasp/esapi/ValidationErrorListTest.java new file mode 100644 index 000000000..42762d7f3 --- /dev/null +++ b/src/test/java/org/owasp/esapi/ValidationErrorListTest.java @@ -0,0 +1,90 @@ +/** + * 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 static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.TestName; +import org.owasp.esapi.errors.ValidationException; + + +/** + * @author Jeff Williams (jeff.williams@aspectsecurity.com) + */ +public class ValidationErrorListTest { + @Rule + public ExpectedException exEx = ExpectedException.none(); + @Rule + public TestName testName = new TestName(); + + ValidationErrorList vel = new ValidationErrorList(); + ValidationException vex = new ValidationException(testName.getMethodName(), testName.getMethodName()); + @Test + public void testAddErrorNullContextThrows() { + exEx.expect(RuntimeException.class); + exEx.expectMessage("Context cannot be null"); + vel.addError(null, vex); + } + + @Test + public void testAddErrorNullExceptionThrows() { + exEx.expect(RuntimeException.class); + exEx.expectMessage("ValidationException cannot be null"); + vel.addError(testName.getMethodName(), null); + } + public void testAddErrorDuplicateContextThrows() { + exEx.expect(RuntimeException.class); + exEx.expectMessage("already exists, must be unique"); + vel.addError(testName.getMethodName(), vex); + vel.addError(testName.getMethodName(), vex); + } + + @Test + public void testErrors() throws Exception { + vel.addError("context", vex ); + assertTrue("Validation Errors List should contain the added ValidationException Reference",vel.errors().contains( vex) ); + } + + @Test + public void testGetError() throws Exception { + vel.addError("context", vex ); + assertTrue( vel.getError( "context" ) == vex ); + assertNull( vel.getError( "ridiculous" ) ); + } + + @Test + public void testIsEmpty() throws Exception { + assertTrue( vel.isEmpty() ); + vel.addError("context", vex ); + assertFalse( vel.isEmpty() ); + } + + @Test + public void testSize() throws Exception { + assertEquals(0, vel.size() ); + vel.addError("context", vex ); + assertEquals(1, vel.size()); + } + +} + + diff --git a/src/test/java/org/owasp/esapi/codecs/AbstractCodecTest.java b/src/test/java/org/owasp/esapi/codecs/AbstractCodecTest.java new file mode 100644 index 000000000..f4f1b7b46 --- /dev/null +++ b/src/test/java/org/owasp/esapi/codecs/AbstractCodecTest.java @@ -0,0 +1,629 @@ +/** + * 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.codecs; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + + + +/** + * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security + * @since June 1, 2007 + */ +public class AbstractCodecTest extends TestCase { + + private static final char[] EMPTY_CHAR_ARRAY = new char[0]; + private static final Character LESS_THAN = Character.valueOf('<'); + private static final Character SINGLE_QUOTE = Character.valueOf('\''); + private HTMLEntityCodec htmlCodec = new HTMLEntityCodec(); + private PercentCodec percentCodec = new PercentCodec(); + private JavaScriptCodec javaScriptCodec = new JavaScriptCodec(); + private VBScriptCodec vbScriptCodec = new VBScriptCodec(); + private CSSCodec cssCodec = new CSSCodec(); + private MySQLCodec mySQLCodecANSI = new MySQLCodec( MySQLCodec.ANSI_MODE ); + private MySQLCodec mySQLCodecStandard = new MySQLCodec( MySQLCodec.MYSQL_MODE ); + private OracleCodec oracleCodec = new OracleCodec(); + private UnixCodec unixCodec = new UnixCodec(); + private WindowsCodec windowsCodec = new WindowsCodec(); + + /** + * Instantiates a new access reference map test. + * + * @param testName + * the test name + */ + public AbstractCodecTest(String testName) { + super(testName); + } + + /** + * {@inheritDoc} + * @throws Exception + */ + protected void setUp() throws Exception { + // none + } + + /** + * {@inheritDoc} + * @throws Exception + */ + protected void tearDown() throws Exception { + // none + } + + /** + * Suite. + * + * @return the test + */ + public static Test suite() { + TestSuite suite = new TestSuite(AbstractCodecTest.class); + return suite; + } + + public void testHtmlEncode() + { + assertEquals( "test", htmlCodec.encode( EMPTY_CHAR_ARRAY, "test") ); + } + + public void testPercentEncode() + { + assertEquals( "%3C", percentCodec.encode(EMPTY_CHAR_ARRAY, "<") ); + } + + + public void testJavaScriptEncode() + { + assertEquals( "\\x3C", javaScriptCodec.encode(EMPTY_CHAR_ARRAY, "<") ); + } + + public void testVBScriptEncode() + { + assertEquals( "chrw(60)", vbScriptCodec.encode(EMPTY_CHAR_ARRAY, "<") ); + } + + public void testCSSEncode() + { + assertEquals( "\\3c ", cssCodec.encode(EMPTY_CHAR_ARRAY, "<") ); + } + + public void testCSSInvalidCodepointDecode() + { + assertEquals("\uFFFDg", cssCodec.decode("\\abcdefg") ); + } + + public void testMySQLANSCIEncode() + { + assertEquals( "\'\'", mySQLCodecANSI.encode(EMPTY_CHAR_ARRAY, "\'") ); + } + + public void testMySQLStandardEncode() + { + assertEquals( "\\<", mySQLCodecStandard.encode(EMPTY_CHAR_ARRAY, "<") ); + } + + public void testOracleEncode() + { + assertEquals( "\'\'", oracleCodec.encode(EMPTY_CHAR_ARRAY, "\'") ); + } + + public void testUnixEncode() + { + assertEquals( "\\<", unixCodec.encode(EMPTY_CHAR_ARRAY, "<") ); + } + + public void testWindowsEncode() + { + assertEquals( "^<", windowsCodec.encode(EMPTY_CHAR_ARRAY, "<") ); + } + + + public void testHtmlEncodeChar() + { + + assertEquals( "<", htmlCodec.encodeCharacter(EMPTY_CHAR_ARRAY, (int) LESS_THAN) ); + } + + public void testHtmlEncodeChar0x100() + { + Character in = 0x100; + String inStr = Character.toString(in); + String expected = "Ā"; + String result; + //The new default for HTMLEntityCodec is ints/Integers. Use Character/char at your own risk! + //Characters destroy non-BMP codepoints. This Codec is now supposed surpass that. + result = htmlCodec.encodeCharacter(EMPTY_CHAR_ARRAY, (int) in); + // this should be escaped + assertFalse(inStr.equals(result)); + // UTF-8 encoded and then percent escaped + assertEquals(expected, result); + } + + public void testHtmlEncodeStr0x100() + { + Character in = 0x100; + String inStr = Character.toString(in); + String expected = "Ā"; + String result; + + result = htmlCodec.encode(EMPTY_CHAR_ARRAY, inStr); + // this should be escaped + assertFalse(inStr.equals(result)); + // UTF-8 encoded and then percent escaped + assertEquals(expected, result); + } + + public void testPercentEncodeChar() + { + assertEquals( "%3C", percentCodec.encodeCharacter(EMPTY_CHAR_ARRAY, LESS_THAN) ); + } + + public void testPercentEncodeChar0x100() + { + Character in = 0x100; + String inStr = Character.toString(in); + String expected = "%C4%80"; + String result; + + result = percentCodec.encodeCharacter(EMPTY_CHAR_ARRAY, in); + // this should be escaped + assertFalse(inStr.equals(result)); + // UTF-8 encoded and then percent escaped + assertEquals(expected, result); + } + + public void testPercentEncodeStr0x100() + { + Character in = 0x100; + String inStr = Character.toString(in); + String expected = "%C4%80"; + String result; + + result = percentCodec.encode(EMPTY_CHAR_ARRAY, inStr); + // this should be escaped + assertFalse(inStr.equals(result)); + // UTF-8 encoded and then percent escaped + assertEquals(expected, result); + } + + public void testJavaScriptEncodeChar() + { + assertEquals( "\\x3C", javaScriptCodec.encodeCharacter(EMPTY_CHAR_ARRAY, LESS_THAN) ); + } + + public void testJavaScriptEncodeChar0x100() + { + Character in = 0x100; + String inStr = Character.toString(in); + String expected = "\\u0100"; + String result; + + result = javaScriptCodec.encodeCharacter(EMPTY_CHAR_ARRAY, in); + // this should be escaped + assertFalse(inStr.equals(result)); + assertEquals(expected,result); + } + + public void testJavaScriptEncodeStr0x100() + { + Character in = 0x100; + String inStr = Character.toString(in); + String expected = "\\u0100"; + String result; + + result = javaScriptCodec.encode(EMPTY_CHAR_ARRAY, inStr); + // this should be escaped + assertFalse(inStr.equals(result)); + assertEquals(expected,result); + } + + public void testVBScriptEncodeChar() + { + assertEquals( "chrw(60)", vbScriptCodec.encodeCharacter(EMPTY_CHAR_ARRAY, LESS_THAN) ); + } + + public void testVBScriptEncodeChar0x100() + { + Character in = 0x100; + String inStr = Character.toString(in); + // FIXME I don't know vb... + // String expected = "\\u0100"; + String result; + + result = vbScriptCodec.encodeCharacter(EMPTY_CHAR_ARRAY, in); + // this should be escaped + assertFalse(inStr.equals(result)); + //assertEquals(expected,result); + } + + public void testVBScriptEncodeStr0x100() + { + Character in = 0x100; + String inStr = Character.toString(in); + // FIXME I don't know vb... + // String expected = "chrw(0x100)"; + String result; + + result = vbScriptCodec.encode(EMPTY_CHAR_ARRAY, inStr); + // this should be escaped + assertFalse(inStr.equals(result)); + // assertEquals(expected,result); + } + + public void testCSSEncodeChar() + { + assertEquals( "\\3c ", cssCodec.encodeCharacter(EMPTY_CHAR_ARRAY, LESS_THAN) ); + } + + public void testCSSEncodeChar0x100() + { + Character in = 0x100; + String inStr = Character.toString(in); + String expected = "\\100 "; + String result; + + result = cssCodec.encodeCharacter(EMPTY_CHAR_ARRAY, in); + // this should be escaped + assertFalse(inStr.equals(result)); + assertEquals(expected,result); + } + + public void testCSSEncodeStr0x100() + { + Character in = 0x100; + String inStr = Character.toString(in); + String expected = "\\100 "; + String result; + + result = cssCodec.encode(EMPTY_CHAR_ARRAY, inStr); + // this should be escaped + assertFalse(inStr.equals(result)); + assertEquals(expected,result); + } + + public void testMySQLANSIEncodeChar() + { + assertEquals( "\'\'", mySQLCodecANSI.encodeCharacter(EMPTY_CHAR_ARRAY, SINGLE_QUOTE)); + } + + public void testMySQLStandardEncodeChar0x100() + { + Character in = 0x100; + String inStr = Character.toString(in); + String expected = "\\" + in; + String result; + + result = mySQLCodecStandard.encodeCharacter(EMPTY_CHAR_ARRAY, in); + // this should be escaped + assertFalse(inStr.equals(result)); + assertEquals(expected,result); + } + + public void testMySQLStandardEncodeStr0x100() + { + Character in = 0x100; + String inStr = Character.toString(in); + String expected = "\\" + in; + String result; + + result = mySQLCodecStandard.encode(EMPTY_CHAR_ARRAY, inStr); + // this should be escaped + assertFalse(inStr.equals(result)); + assertEquals(expected,result); + } + + public void testMySQLStandardEncodeChar() + { + assertEquals( "\\<", mySQLCodecStandard.encodeCharacter(EMPTY_CHAR_ARRAY, LESS_THAN) ); + } + + public void testOracleEncodeChar() + { + assertEquals( "\'\'", oracleCodec.encodeCharacter(EMPTY_CHAR_ARRAY, SINGLE_QUOTE) ); + } + + public void testUnixEncodeChar() + { + assertEquals( "\\<", unixCodec.encodeCharacter(EMPTY_CHAR_ARRAY, LESS_THAN) ); + } + + public void testUnixEncodeChar0x100() + { + Character in = 0x100; + String inStr = Character.toString(in); + String expected = "\\" + in; + String result; + + result = unixCodec.encodeCharacter(EMPTY_CHAR_ARRAY, in); + // this should be escaped + assertFalse(inStr.equals(result)); + assertEquals(expected,result); + } + + public void testUnixEncodeStr0x100() + { + Character in = 0x100; + String inStr = Character.toString(in); + String expected = "\\" + in; + String result; + + result = unixCodec.encode(EMPTY_CHAR_ARRAY, inStr); + // this should be escaped + assertFalse(inStr.equals(result)); + assertEquals(expected,result); + } + + public void testWindowsEncodeChar() + { + assertEquals( "^<", windowsCodec.encodeCharacter(EMPTY_CHAR_ARRAY, LESS_THAN) ); + } + + public void testWindowsEncodeChar0x100() + { + Character in = 0x100; + String inStr = Character.toString(in); + String expected = "^" + in; + String result; + + result = windowsCodec.encodeCharacter(EMPTY_CHAR_ARRAY, in); + // this should be escaped + assertFalse(inStr.equals(result)); + assertEquals(expected,result); + } + + public void testWindowsEncodeStr0x100() + { + Character in = 0x100; + String inStr = Character.toString(in); + String expected = "^" + in; + String result; + + result = windowsCodec.encode(EMPTY_CHAR_ARRAY, inStr); + // this should be escaped + assertFalse(inStr.equals(result)); + assertEquals(expected,result); + } + + public void testHtmlDecodeDecimalEntities() + { + assertEquals( "test!", htmlCodec.decode("test!") ); + } + + public void testHtmlDecodeHexEntitites() + { + assertEquals( "test!", htmlCodec.decode("test!") ); + } + + public void testHtmlDecodeInvalidAttribute() + { + assertEquals( "&jeff;", htmlCodec.decode("&jeff;") ); + } + + public void testHtmlDecodeAmp() + { + assertEquals("&", htmlCodec.decode("&")); + assertEquals("&X", htmlCodec.decode("&X")); + assertEquals("&", htmlCodec.decode("&")); + assertEquals("&X", htmlCodec.decode("&X")); + } + + public void testHtmlDecodeLt() + { + assertEquals("<", htmlCodec.decode("<")); + assertEquals("', ';' }; + + + @Parameters(name = "{0}") + public static Collection getParams() { + Collection knownCodecs = new ArrayList(); + knownCodecs.add(new CSSCodec()); + knownCodecs.add(new DB2Codec()); + knownCodecs.add(new HTMLEntityCodec()); + knownCodecs.add(new JavaScriptCodec()); + knownCodecs.add(new MySQLCodec(0)); //Standard + knownCodecs.add(new MySQLCodec(1)); //ANSI + knownCodecs.add(new OracleCodec()); + knownCodecs.add(new PercentCodec()); + knownCodecs.add(new UnixCodec()); + knownCodecs.add(new VBScriptCodec()); + knownCodecs.add(new WindowsCodec()); + knownCodecs.add(new XMLEntityCodec()); + + // TODO: Add more strings here!! + List sampleStrings = Arrays.asList("%De"); + + Collection params = new ArrayList(); + for (Codec codec : knownCodecs) { + for (String sample : sampleStrings) { + params.add(new Object[]{codec.getClass().getSimpleName() + " " + sample, codec, sample}); + } + } + + // Add Tests for codecs against the configured ImmunityLists within the Default Encoder. + params.addAll(buildImmunitiyValidation(new HTMLEntityCodec(), IMMUNE_HTML, "IMMUNE_HTML")); + params.addAll(buildImmunitiyValidation(new HTMLEntityCodec(), IMMUNE_XPATH, "IMMUNE_XPATH")); + params.addAll(buildImmunitiyValidation(new HTMLEntityCodec(), IMMUNE_HTMLATTR, "IMMUNE_HTMLATTR")); + params.addAll(buildImmunitiyValidation(new CSSCodec(), IMMUNE_CSS, "IMMUNE_CSS")); + //params.addAll(buildImmunitiyValidation(new DB2Codec(), IMMUNE_HTML, "")); + params.addAll(buildImmunitiyValidation(new JavaScriptCodec(), IMMUNE_JAVASCRIPT, "IMMUNE_JAVASCRIPT")); + params.addAll(buildImmunitiyValidation(new MySQLCodec(0), IMMUNE_SQL, "IMMUNE_SQL")); + params.addAll(buildImmunitiyValidation(new MySQLCodec(1), IMMUNE_SQL, "IMMUNE_SQL")); + params.addAll(buildImmunitiyValidation(new OracleCodec(), IMMUNE_HTML, "IMMUNE_HTML")); + // No standard Immunity char array defined for PercentEncoder, but for + // GitHub issues #306 and $350, we use '%'. + params.addAll(buildImmunitiyValidation(new PercentCodec(), IMMUNE_PERCENT, "IMMUNE_PERCENT")); + params.addAll(buildImmunitiyValidation(new UnixCodec(), IMMUNE_OS, "IMMUNE_OS")); + params.addAll(buildImmunitiyValidation(new VBScriptCodec(), IMMUNE_VBSCRIPT, "IMMUNE_VBSCRIPT")); + params.addAll(buildImmunitiyValidation(new WindowsCodec(), IMMUNE_OS, "IMMUNE_OS")); + params.addAll(buildImmunitiyValidation(new XMLEntityCodec(), IMMUNE_XML, "IMMUNE_XML")); + params.addAll(buildImmunitiyValidation(new XMLEntityCodec(), IMMUNE_XMLATTR, "IMMUNE_XMLATTR")); + + params.addAll(fullCharacterCodecValidation(knownCodecs)); + + return params; + } + + private static Collection buildImmunitiyValidation(Codec codec, char[] immunities, String descriptor) { + Collection params = new ArrayList(); + for (char c : immunities) { + params.add(new Object[]{codec.getClass().getSimpleName() + " " + descriptor + " ("+ c + ")", codec, String.valueOf(c)}); + } + return params; + } + + private static Collection fullCharacterCodecValidation(Collection codecs) { + char[] holyCowTesting = StringUtilities.union(EncoderConstants.CHAR_ALPHANUMERICS, EncoderConstants.CHAR_SPECIALS); + Collection params = new ArrayList(); + for (Codec codec: codecs) { + params.addAll(buildImmunitiyValidation(codec, holyCowTesting, "Full_ALPHA_AND_SPECIALS")); + } + + return params; + } + + private final Codec codec; + private final String string; + private final char[] immunityList; + + public CodecImmunityTest(String ignored, Codec codec, String toTest) { + this.codec = codec; + this.string = toTest; + /** + * The Immunity character array is every character in the String we're testing. + * + */ + this.immunityList = toTest.toCharArray(); + } + + @Test + public void testImmuneEncode() { + String encoded = codec.encode(immunityList, string); + Assert.assertEquals(string, encoded); + } + /* + @Test + public void testImmuneDecode() { + String decoded = codec.decode(string); + Assert.assertEquals(string, decoded); + } +*/ +} diff --git a/src/test/java/org/owasp/esapi/codecs/HTMLEntityCodecTest.java b/src/test/java/org/owasp/esapi/codecs/HTMLEntityCodecTest.java new file mode 100644 index 000000000..869871c1c --- /dev/null +++ b/src/test/java/org/owasp/esapi/codecs/HTMLEntityCodecTest.java @@ -0,0 +1,52 @@ +package org.owasp.esapi.codecs; + +import static org.junit.Assert.assertEquals; + +import org.junit.Ignore; +import org.junit.Test; + +public class HTMLEntityCodecTest { + Codec codec = new HTMLEntityCodec(); + + @Test + public void testEntityDecoding(){ + assertEquals("<", codec.decode("<")); + assertEquals( "<", codec.decode("<")); + assertEquals( "<", codec.decode("<")); + assertEquals( "<", codec.decode("<")); + } + + @Test + public void test32BitCJK(){ + String s = "đˇľđ¦´©đĄ»‚"; + String expected = "𡘾𦴩𥻂"; + String bad = "������"; + assertEquals(false, expected.equals(bad)); + assertEquals(expected, codec.encode(new char[0], s)); + } + + @Test + public void test32BitCJKMixedWithBmp(){ + String s = "đˇľđ¦´©<𥻂"; + String expected = "𡘾𦴩<𥻂"; + String bad = "������"; + assertEquals(false, expected.equals(bad)); + assertEquals(expected, codec.encode(new char[0], s)); + } + + @Test + public void testDecodeforChars(){ + String s = "!@$%()=+{}[]"; + String expected = "!@$%()=+{}[]"; + assertEquals(expected, codec.decode(s)); + } + + @Test + public void testMixedBmpAndNonBmp(){ + String nonBMP = new String(new int[]{0x2f804}, 0, 1); + String bmp = " CLASS = HashTrieTest.class; + + public HashTrieTest(String testName) + { + super(testName); + } + + public void testSingleInsertLookup() + { + HashTrie trie = new HashTrie(); + + trie.put("true", Boolean.TRUE); + assertEquals(Boolean.TRUE, trie.get("true")); + assertNull(trie.get("not there")); + assertNull(trie.get("tru")); + assertNull(trie.get("trueX")); + assertEquals("true".length(), trie.getMaxKeyLength()); + } + + public void testEmpty() + { + HashTrie trie = new HashTrie(); + assertNull(trie.get("true")); + assertNull(trie.get("false")); + assertNull(trie.get("")); + assertTrue(trie.getMaxKeyLength()<0); + } + + public void testTwoInsertLookup() + { + HashTrie trie = new HashTrie(); + + trie.put("true", Boolean.TRUE); + trie.put("false", Boolean.FALSE); + assertEquals(Boolean.TRUE, trie.get("true")); + assertEquals(Boolean.FALSE, trie.get("false")); + assertEquals("false".length(),trie.getMaxKeyLength()); + } + + public void testMatchingPrefix() + { + HashTrie trie = new HashTrie(); + + trie.put("pretrue", Boolean.TRUE); + trie.put("prefalse", Boolean.FALSE); + assertEquals(Boolean.TRUE, trie.get("pretrue")); + assertEquals(Boolean.FALSE, trie.get("prefalse")); + } + + public void testPrefixIsValidKey() + { + HashTrie trie = new HashTrie(); + + trie.put("pre", Boolean.TRUE); + trie.put("prefalse", Boolean.FALSE); + assertEquals(Boolean.TRUE, trie.get("pre")); + assertEquals(Boolean.FALSE, trie.get("prefalse")); + } + + public void testDuplicateAdd() + { + HashTrie trie = new HashTrie(); + + assertNull(trie.put("dup", Boolean.TRUE)); + assertTrue(trie.put("dup", Boolean.FALSE)); + assertFalse(trie.get("dup")); + } + + public void testTwoInsertLongestLookup() + { + HashTrie trie = new HashTrie(); + Entry entry; + + trie.put("true", Boolean.TRUE); + trie.put("true idea", Boolean.TRUE); + trie.put("false", Boolean.FALSE); + + assertNotNull((entry = trie.getLongestMatch("true"))); + assertEquals("true", entry.getKey()); + assertTrue(entry.getValue()); + + assertNotNull((entry = trie.getLongestMatch("false"))); + assertEquals("false", entry.getKey()); + assertFalse(entry.getValue()); + + assertNotNull((entry = trie.getLongestMatch("truer"))); + assertEquals("true", entry.getKey()); + assertTrue(entry.getValue()); + + assertNotNull((entry = trie.getLongestMatch("true to form"))); + assertEquals("true", entry.getKey()); + assertTrue(entry.getValue()); + + assertNotNull((entry = trie.getLongestMatch("false result"))); + assertEquals("false", entry.getKey()); + assertFalse(entry.getValue()); + + assertNull(trie.getLongestMatch("not there")); + assertNull(trie.getLongestMatch("tru")); + assertNull(trie.getLongestMatch("fals")); + } + + public void testContainsKey() + { + HashTrie trie = new HashTrie(); + + trie.put("true", Boolean.TRUE); + trie.put("false", Boolean.FALSE); + assertTrue(trie.containsKey("true")); + assertTrue(trie.containsKey("false")); + assertFalse(trie.containsKey("not there")); + } + + public void testContainsValue() + { + HashTrie trie = new HashTrie(); + + trie.put("one", 1); + trie.put("two", 2); + assertTrue(trie.containsValue(1)); + assertTrue(trie.containsValue(2)); + assertFalse(trie.containsValue(3)); + } + + public void testKeySet() + { + HashTrie trie = new HashTrie(); + HashSet expected = new HashSet(2); + + expected.add("true"); + expected.add("false"); + trie.put("true", Boolean.TRUE); + trie.put("false", Boolean.FALSE); + assertEquals(expected,trie.keySet()); + } + + public void testValues() + { + HashTrie trie = new HashTrie(); + ArrayList actual; + ArrayList expected = new ArrayList(2); + + expected.add(Boolean.TRUE); + expected.add(Boolean.FALSE); + trie.put("true", Boolean.TRUE); + trie.put("false", Boolean.FALSE); + actual = new ArrayList(trie.values()); + Collections.sort(actual); + Collections.sort(expected); + assertEquals(expected,actual); + } + + public void testEntrySet() + { + HashTrie trie = new HashTrie(); + HashMap equivMap = new HashMap(2); + + equivMap.put("true",Boolean.TRUE); + equivMap.put("false",Boolean.FALSE); + trie.put("true", Boolean.TRUE); + trie.put("false", Boolean.FALSE); + assertEquals(equivMap.entrySet(),trie.entrySet()); + } + + public void testEquals() + { + HashTrie trie = new HashTrie(); + HashMap equivMap = new HashMap(2); + + equivMap.put("true",Boolean.TRUE); + equivMap.put("false",Boolean.FALSE); + trie.put("true", Boolean.TRUE); + trie.put("false", Boolean.FALSE); + assertTrue(trie.equals(equivMap)); + } + + public void testHashCode() + { + HashTrie trie = new HashTrie(); + HashMap equivMap = new HashMap(2); + + equivMap.put("true",Boolean.TRUE); + equivMap.put("false",Boolean.FALSE); + trie.put("true", Boolean.TRUE); + trie.put("false", Boolean.FALSE); + assertEquals(equivMap.hashCode(),trie.hashCode()); + } + + /** + * Create a test suite with just this test. + * @return A test swuite with just this test. + */ + public static Test suite() + { + TestSuite suite = new TestSuite(CLASS); + return suite; + } +} diff --git a/src/test/java/org/owasp/esapi/codecs/MySQLCodecTest.java b/src/test/java/org/owasp/esapi/codecs/MySQLCodecTest.java new file mode 100644 index 000000000..f6cca0645 --- /dev/null +++ b/src/test/java/org/owasp/esapi/codecs/MySQLCodecTest.java @@ -0,0 +1,366 @@ +package org.owasp.esapi.codecs; + +import java.util.HashMap; +import java.util.Map; + +import org.hamcrest.Matcher; +import org.hamcrest.core.IsEqual; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ErrorCollector; +import org.junit.rules.ExpectedException; +import org.mockito.Mockito; +import org.owasp.esapi.codecs.MySQLCodec.Mode; +import org.powermock.reflect.Whitebox; +/** + * Tests to show {@link MySQLCodec} with {@link Mode#ANSI} + * comply with the OWASP Escaping recommendations + * + * https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet#MySQL_Escaping + * + */ +public class MySQLCodecTest { + private static final char[] EMPTY_CHAR_ARRAY = new char[0]; + private static Map ANSI_ESCAPES; + private static Map STANDARD_ESCAPES; + + private static final InclusiveRangePair NUMBER_CHAR_RANGE = new InclusiveRangePair(48,57); + private static final InclusiveRangePair UPPER_CHAR_RANGE = new InclusiveRangePair(65,90); + private static final InclusiveRangePair LOWER_CHAR_RANGE = new InclusiveRangePair(97,122); + + private MySQLCodec uitAnsi = new MySQLCodec(Mode.ANSI); + private MySQLCodec uitMySqlStandard = new MySQLCodec(Mode.STANDARD); + + + @Rule + public ErrorCollector errorCollector = new ErrorCollector(); + @Rule + public ExpectedException exEx = ExpectedException.none(); + + + @BeforeClass + public static void createCodecEscapeMaps () { + Map escapesStd = new HashMap<>(); + escapesStd.put( (char)0x00, "\\0"); + escapesStd.put( (char)0x08, "\\b"); + escapesStd.put( (char)0x09, "\\t"); + escapesStd.put( (char)0x0a, "\\n"); + escapesStd.put( (char)0x0d, "\\r"); + escapesStd.put( (char)0x1a, "\\Z"); + escapesStd.put( (char)0x22, "\\\""); + escapesStd.put( (char)0x25, "\\%"); + escapesStd.put( (char)0x27, "\\'"); + escapesStd.put( (char)0x5c, "\\\\"); + escapesStd.put( (char)0x5f, "\\_"); + + Map escapesAnsi = new HashMap<>(); + escapesAnsi.put( '\'', "\'\'"); + + STANDARD_ESCAPES = escapesStd; + ANSI_ESCAPES = escapesAnsi; + } + + /** + * ANSI + * Test showing that for characters up to 256, the only encoded value is the single tick. + * + * when the single tick is encoded, it is updated to be double tick. All other characters remain unchanged. + */ + @Test + public void testAnsiEncodeTo256() { + for (int ref = 0 ; ref < 256; ref ++) { + char refChar = (char) ref; + boolean shouldEscape = ANSI_ESCAPES.containsKey(refChar); + + + String charAsString = "" + refChar; + String expected = charAsString; + String encodeMsg = String.format("%s (%s) should not be altered when Encoded through the ANSI MySQLCodec", charAsString, ref); + String decodeMsg = String.format("%s (%s) [%s] should match original value when DECODED through the ANSI MySQLCodec", charAsString, ref, expected); + if (shouldEscape) { + expected = ANSI_ESCAPES.get(refChar); + encodeMsg = String.format("%s (%s) should have been escaped when Encoded through the ANSI MySQLCodec", charAsString, ref); + } + Matcher encodeExpect = new IsEqual<>(expected); + Matcher decodeExpect = new IsEqual<>(charAsString); + errorCollector.checkThat(encodeMsg, uitAnsi.encode(EMPTY_CHAR_ARRAY, charAsString), encodeExpect); + errorCollector.checkThat(decodeMsg, uitAnsi.decode(expected), decodeExpect); + } + } + @Test + public void testAnsiEncodeWithImmuneSet() { + //The only value that is encoded is single tick. The immunity list does not impact normal capability in ANSI mode + char[] immuneChars = new char[] {15, 91,150, 255}; + + for (char refChar : immuneChars) { + int ref = refChar; + String charAsString = "" + refChar; + String expected = charAsString; + String encodeMsg = String.format("%s (%s) should not be escaped when in the immunity list provided to Encoded through the ANSI MySQLCodec", charAsString, refChar); + String decodeMsg = String.format("%s (%s) [%s] should match original value when Encoded through the ANSI MySQLCodec", charAsString, ref, expected); + + Matcher encodeExpect = new IsEqual<>(expected); + Matcher decodeExpect = new IsEqual<>(charAsString); + errorCollector.checkThat(encodeMsg, uitAnsi.encode(immuneChars, charAsString), encodeExpect); + errorCollector.checkThat(decodeMsg, uitAnsi.decode(expected), decodeExpect); + } + } + /** Upper case letters should not be mutated by the implementation.*/ + @Test + public void testStandardEncodeUpperCaseRange() { + performStandardNonEscapeTest(UPPER_CHAR_RANGE); + } + /** Lower case letters should not be mutated by the implementation.*/ + @Test + public void testStandardEncodeLowerCaseRange() { + performStandardNonEscapeTest(LOWER_CHAR_RANGE); + } + /** Numbers should not be mutated by the implementation.*/ + @Test + public void testStandardEncodeNumbersRange() { + performStandardNonEscapeTest(NUMBER_CHAR_RANGE); + } + + /** + * Helper function for iterating a defined range of values and asserting encoded references are not mutated. + * @param range {@link InclusiveRangePair} reference to verify + */ + private void performStandardNonEscapeTest(InclusiveRangePair range) { + for (int ref = range.getLowerLimit() ; ref <= range.getUpperLimit(); ref ++) { + char refChar = (char) ref; + String charAsString = "" + refChar; + String expected = charAsString; + String encodeMsg = String.format("%s (%s) should not be changed when Encoded through the Standard MySQLCodec", charAsString, ref); + String decodeMsg = String.format("%s (%s) [%s] should match original value when Encoded through the Standard MySQLCodec", charAsString, ref, expected); + + Matcher encodeExpect = new IsEqual<>(expected); + Matcher decodeExpect = new IsEqual<>(charAsString); + errorCollector.checkThat(encodeMsg, uitMySqlStandard.encode(EMPTY_CHAR_ARRAY, charAsString), encodeExpect); + errorCollector.checkThat(decodeMsg, uitMySqlStandard.decode(expected), decodeExpect); + } + } + + /** + * Tests that any value under 256 that is not a number, upper case letter, lower case letter, or a special-encoding object is prefixed by a backslash when encoded + * by a STANDARD MySQLCodec implementation + */ + @Test + public void testStandardEncodeNonAlphaNumeric() { + for (int ref = 0; ref < 256 ; ref ++) { + char refChar = (char) ref; + if (NUMBER_CHAR_RANGE.contains(ref) || LOWER_CHAR_RANGE.contains(ref) || UPPER_CHAR_RANGE.contains(ref) || STANDARD_ESCAPES.keySet().contains(refChar)) { + continue; + } + String charAsString = "" + refChar; + String expected = "\\" + charAsString; + String encodeMsg = String.format("%s (%s) should have been escaped when Encoded through the Standard MySQLCodec", charAsString, refChar); + String decodeMsg = String.format("%s (%s) [%s] should match original value when Encoded through the Standard MySQLCodec", charAsString, ref, expected); + + Matcher encodeExpect = new IsEqual<>(expected); + Matcher decodeExpect = new IsEqual<>(charAsString); + errorCollector.checkThat(encodeMsg, uitMySqlStandard.encode(EMPTY_CHAR_ARRAY, charAsString), encodeExpect); + errorCollector.checkThat(decodeMsg, uitMySqlStandard.decode(expected), decodeExpect); + + } + } + + @Test + public void testStandardEncodeWithImmuneSet() { + //These values normally fall under the encodeNonAlphaNumeric test content. + char[] immuneChars = new char[] {15, 91,150, 255}; + + for (char refChar : immuneChars) { + int ref = refChar; + String charAsString = "" + refChar; + //Typically, we should expect the encode to be the original value prefixed by two backslashes. + String expected = charAsString; + String encodeMsg = String.format("%s (%s) should not be escaped when in the immunity list provided to Encoded through the Standard MySQLCodec", charAsString, refChar); + String decodeMsg = String.format("%s (%s) [%s] should match original value when Encoded through the Standard MySQLCodec", charAsString, ref, expected); + + Matcher encodeExpect = new IsEqual<>(expected); + Matcher decodeExpect = new IsEqual<>(charAsString); + errorCollector.checkThat(encodeMsg, uitMySqlStandard.encode(immuneChars, charAsString), encodeExpect); + errorCollector.checkThat(decodeMsg, uitMySqlStandard.decode(expected), decodeExpect); + } + } + /** + * Asserts that predefined specialty escape sequences are provided when encoded. + */ + @Test + public void testStandardEncodeEscapeSet() { + for (Character refChar : STANDARD_ESCAPES.keySet()) { + String charAsString = "" + refChar; + String expected = STANDARD_ESCAPES.get(refChar); + String encodeMsg = String.format("%s (%s) should have been escaped when Encoded through the Standard MySQLCodec", charAsString, (int) refChar.charValue()); + String decodeMsg = String.format("%s (%s) [%s] should match original value when Encoded through the Standard MySQLCodec", charAsString, (int) refChar.charValue(), expected); + + Matcher encodeExpect = new IsEqual<>(expected); + Matcher decodeExpect = new IsEqual<>(charAsString); + errorCollector.checkThat(encodeMsg, uitMySqlStandard.encode(EMPTY_CHAR_ARRAY, charAsString), encodeExpect); + errorCollector.checkThat(decodeMsg, uitMySqlStandard.decode(expected), decodeExpect); + } + } + + /** + * If the first element in the {@link PushbackSequence} is null, then null is expected. + */ + @Test + public void testAnsiDecodePushbackSequenceNullFirstElementReturnsNull() { + PushbackSequence mockPushback = Mockito.mock(PushbackSequence.class); + Mockito.when(mockPushback.next()).thenReturn(null); + + Character decChar = uitAnsi.decodeCharacter(mockPushback); + Assert.assertNull(decChar); + + Mockito.verify(mockPushback, Mockito.times(1)).mark(); + Mockito.verify(mockPushback, Mockito.times(1)).next(); + Mockito.verify(mockPushback, Mockito.times(1)).reset(); + + } + + /** + * If the first character is a single tick, and the second character is null, null is expected + */ + @Test + public void testAnsiDecodePushbackSequenceNullSecondElementReturnsNull() { + PushbackSequence mockPushback = Mockito.mock(PushbackSequence.class); + Mockito.when(mockPushback.next()).thenReturn('\'').thenReturn(null); + + Character decChar = uitAnsi.decodeCharacter(mockPushback); + Assert.assertNull(decChar); + + Mockito.verify(mockPushback, Mockito.times(1)).mark(); + Mockito.verify(mockPushback, Mockito.times(2)).next(); + Mockito.verify(mockPushback, Mockito.times(1)).reset(); + + } + + /** + * If the first character is a single tick and the second character is NOT a single tick (escaped tick), then null is expected. + */ + @Test + public void testAnsiDecodePushbackSequenceNonTickSecondElmentReturnsNull() { + PushbackSequence mockPushback = Mockito.mock(PushbackSequence.class); + Mockito.when(mockPushback.next()).thenReturn('\'').thenReturn('A'); + + Character decChar = uitAnsi.decodeCharacter(mockPushback); + Assert.assertNull(decChar); + + Mockito.verify(mockPushback, Mockito.times(1)).mark(); + Mockito.verify(mockPushback, Mockito.times(2)).next(); + Mockito.verify(mockPushback, Mockito.times(1)).reset(); + + } + /** + * If two single ticks are read in sequence, a single tick is expected. + */ + @Test + public void testAnsiDecodePushbackSequenceReturnsSingleTick() { + PushbackSequence mockPushback = Mockito.mock(PushbackSequence.class); + Mockito.when(mockPushback.next()).thenReturn('\'').thenReturn('\''); + + Character decChar = uitAnsi.decodeCharacter(mockPushback); + Assert.assertEquals('\'', decChar.charValue()); + + Mockito.verify(mockPushback, Mockito.times(1)).mark(); + Mockito.verify(mockPushback, Mockito.times(2)).next(); + Mockito.verify(mockPushback, Mockito.times(0)).reset(); + + } + + /** + * If the first character is not a single tick, null is returned. + */ + @Test + public void testAnsiDecodePushbackSequenceNonTickFirstElementReturnsNull() { + PushbackSequence mockPushback = Mockito.mock(PushbackSequence.class); + Mockito.when(mockPushback.next()).thenReturn('A'); + + Character decChar = uitAnsi.decodeCharacter(mockPushback); + Assert.assertNull(decChar); + + Mockito.verify(mockPushback, Mockito.times(1)).mark(); + Mockito.verify(mockPushback, Mockito.times(1)).next(); + Mockito.verify(mockPushback, Mockito.times(1)).reset(); + + } + + /** + * If the first character is null, null is expected + */ + @Test + public void testStandardDecodePushbackSequenceNullFirstElementReturnsNull() { + PushbackSequence mockPushback = Mockito.mock(PushbackSequence.class); + Mockito.when(mockPushback.next()).thenReturn(null); + + Character decChar = uitMySqlStandard.decodeCharacter(mockPushback); + Assert.assertNull(decChar); + + Mockito.verify(mockPushback, Mockito.times(1)).mark(); + Mockito.verify(mockPushback, Mockito.times(1)).next(); + Mockito.verify(mockPushback, Mockito.times(1)).reset(); + + } + /** + * If the first character is a backslash, and the second character is null, null is expected + */ + @Test + public void testStandardDecodePushbackSequenceNullSecondElementReturnsNull() { + PushbackSequence mockPushback = Mockito.mock(PushbackSequence.class); + Mockito.when(mockPushback.next()).thenReturn('\\').thenReturn(null); + + Character decChar = uitMySqlStandard.decodeCharacter(mockPushback); + Assert.assertNull(decChar); + + Mockito.verify(mockPushback, Mockito.times(1)).mark(); + Mockito.verify(mockPushback, Mockito.times(2)).next(); + Mockito.verify(mockPushback, Mockito.times(1)).reset(); + + } + + @Test + public void testCreateAnsiByInt() { + MySQLCodec codec = new MySQLCodec(MySQLCodec.ANSI_MODE); + Object configMode = Whitebox.getInternalState(codec, "mode"); + Assert.assertEquals(Mode.ANSI, configMode); + } + + @Test + public void testCreateStandardByInt() { + MySQLCodec codec = new MySQLCodec(MySQLCodec.MYSQL_MODE); + Object configMode = Whitebox.getInternalState(codec, "mode"); + Assert.assertEquals(Mode.STANDARD, configMode); + } + + @Test + public void testCreateUnsupportedModeByInt() { + exEx.expect(IllegalArgumentException.class); + String message = String.format("No Mode for %s. Valid references are MySQLStandard: %s or ANSI: %s", Integer.MIN_VALUE, MySQLCodec.MYSQL_MODE, MySQLCodec.ANSI_MODE); + exEx.expectMessage(message); + new MySQLCodec(Integer.MIN_VALUE); + + } + private static class InclusiveRangePair { + private final int upperInclusive; + private final int lowerInclusive; + + public InclusiveRangePair (int minValueAllowed,int maxValueAllowed) { + upperInclusive = maxValueAllowed; + lowerInclusive = minValueAllowed; + } + + public boolean contains (int value) { + return value >= lowerInclusive && value <= upperInclusive; + } + + public int getUpperLimit() { + return upperInclusive; + } + + public int getLowerLimit() { + return lowerInclusive; + } + } +} diff --git a/src/test/java/org/owasp/esapi/codecs/PercentCodecTest.java b/src/test/java/org/owasp/esapi/codecs/PercentCodecTest.java new file mode 100644 index 000000000..5cc9f261b --- /dev/null +++ b/src/test/java/org/owasp/esapi/codecs/PercentCodecTest.java @@ -0,0 +1,16 @@ +package org.owasp.esapi.codecs; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class PercentCodecTest { + + @Test + public void testPercentDecode(){ + Codec codec = new PercentCodec(); + + String expected = " "; + assertEquals(expected, codec.decode("%20")); + } +} diff --git a/src/test/java/org/owasp/esapi/codecs/PushBackStringTest.java b/src/test/java/org/owasp/esapi/codecs/PushBackStringTest.java new file mode 100644 index 000000000..1f7ad61fd --- /dev/null +++ b/src/test/java/org/owasp/esapi/codecs/PushBackStringTest.java @@ -0,0 +1,41 @@ +package org.owasp.esapi.codecs; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class PushBackStringTest { + + @Test + public void testPushbackString() { + PushbackSequence pbs = new PushbackString("012345"); + + pbs.mark(); + assertEquals(0, pbs.index()); + Character first = pbs.next(); + + System.out.println("0x" + Integer.toHexString(first)); + + assertEquals("0", new StringBuilder().appendCodePoint(first).toString()); + } + + @Test + public void testPushbackSequence() { + AbstractPushbackSequence pbs = new PushBackSequenceImpl("12345"); + + pbs.mark(); + assertEquals(0, pbs.index()); + Integer first = pbs.next(); + + System.out.println("0x" + Integer.toHexString(first)); + + assertEquals("&", new StringBuilder().appendCodePoint(first).toString()); + + Integer second = pbs.next(); + + if(second == '#'){ + System.out.printf("[%d]:[%d]\n", second, (int) '#'); + + } + } +} diff --git a/src/test/java/org/owasp/esapi/codecs/XMLEntityCodecTest.java b/src/test/java/org/owasp/esapi/codecs/XMLEntityCodecTest.java new file mode 100644 index 000000000..801d33f3d --- /dev/null +++ b/src/test/java/org/owasp/esapi/codecs/XMLEntityCodecTest.java @@ -0,0 +1,253 @@ +/** + * 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) 2009 - 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.codecs; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.owasp.esapi.util.CollectionsUtil; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +public class XMLEntityCodecTest extends TestCase +{ + private static final char[] EMPTY_CHAR_ARRAY = new char[0]; + private static final String ALPHA_NUMERIC_STR = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + private static final String UNENCODED_STR = ALPHA_NUMERIC_STR + " \t"; + private static final Set UNENCODED_SET = CollectionsUtil.strToUnmodifiableSet(UNENCODED_STR); + private XMLEntityCodec codec = null; + + protected void setUp() + { + codec = new XMLEntityCodec(); + } + + protected void tearDown() + { + codec = null; + } + + public void testEncodeUnencoded() + { + StringBuilder sb = new StringBuilder("AB_YZ"); + String str; + + for(char ch : UNENCODED_SET) + { + sb.setCharAt(2,ch); + str = sb.toString(); + assertEquals(str, codec.encode(EMPTY_CHAR_ARRAY, str)); + } + } + + public void testEncodeOthers() + { + StringBuilder inSb = new StringBuilder("AB_YZ"); + StringBuilder outSb = new StringBuilder("AB&#x"); + String in; + String expected; + String result; + int outSbBaseLen = outSb.length(); + String out; + + for(int c=Character.MIN_VALUE;c<=Character.MAX_VALUE;c++) + { + char ch = (char)c; + if(UNENCODED_SET.contains(ch)) + continue; + inSb.setCharAt(2,ch); + in = inSb.toString(); + outSb.append(Integer.toHexString(c)); + outSb.append(";YZ"); + expected = outSb.toString(); + result = codec.encode(EMPTY_CHAR_ARRAY,in); + assertEquals(expected, result); + outSb.setLength(outSbBaseLen); + } + } + + public void testDecodeUnencoded() + { + StringBuilder sb = new StringBuilder("AB_YZ"); + String str; + + for(char ch : UNENCODED_SET) + { + sb.setCharAt(2,ch); + str = sb.toString(); + assertEquals(str, codec.decode(str)); + } + } + + public void testDecodeHex() + { + StringBuilder expectedSb = new StringBuilder("AB_YZ"); + StringBuilder inSb = new StringBuilder("AB&#x"); + String in; + String expected; + String result; + int inSbBaseLen = inSb.length(); + + for(int c=Character.MIN_VALUE;c<=Character.MAX_VALUE;c++) + { + char ch = (char)c; + expectedSb.setCharAt(2,ch); + expected = expectedSb.toString(); + inSb.append(Integer.toHexString(c)); + inSb.append(";YZ"); + in = inSb.toString(); + result = codec.decode(in); + assertEquals(expected, result); + inSb.setLength(inSbBaseLen); + } + } + + public void testDecodeDec() + { + StringBuilder expectedSb = new StringBuilder("AB_YZ"); + StringBuilder inSb = new StringBuilder("AB&#"); + String in; + String expected; + String result; + int inSbBaseLen = inSb.length(); + + for(int c=Character.MIN_VALUE;c<=Character.MAX_VALUE;c++) + { + char ch = (char)c; + expectedSb.setCharAt(2,ch); + expected = expectedSb.toString(); + inSb.append(Integer.toString(c)); + inSb.append(";YZ"); + in = inSb.toString(); + result = codec.decode(in); + assertEquals(expected, result); + inSb.setLength(inSbBaseLen); + } + } + + public void testDecodeLt() + { + String in = "AB<YZ"; + String expected = "ABhttp://www.owasp.org/index.php/ESAPI. + * + * Copyright (c) 2008-2018 - 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.codecs.abstraction; + +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.owasp.esapi.codecs.Codec; +import org.owasp.esapi.codecs.PushbackString; + + +/** + * Abstract parameterized test case meant to assist with verifying Character api of a Codec implementation. + *
+ * Sub-classes are expected to provide instances of {@link CodecCharacterTestTuple} to this instance. + *
+ * For better test naming output specify {@link CodecCharacterTestTuple#description} and use @Parameters (name="{0}"), + * where '0' is the index that the CodecCharacterTestTuple reference appears in the constructor. + */ +@RunWith(Parameterized.class) +public abstract class AbstractCodecCharacterTest { + + /** Test Data Tuple.*/ + protected static class CodecCharacterTestTuple { + /** Codec reference to be tested.*/ + public Codec codec; + /** Set of characters that should be considered 'immune' from decoding processes.*/ + public char[] encodeImmune; + /** A String representing a single encoded character.*/ + public String input; + /** The single character that input represents.*/ + public Character decodedValue; + /** Optional field to override the toString value of this tuple. */ + public String description; + + /**Default public constructor.*/ + public CodecCharacterTestTuple() { /* No Op*/ } + /** {@inheritDoc}*/ + @Override + public String toString() { + return description != null ? description : codec.getClass().getSimpleName() + " "+input; + } + } + + + protected final Codec codec; + protected final String input; + protected final char[] encodeImmune; + protected final Character decodedValue; + + public AbstractCodecCharacterTest(CodecCharacterTestTuple tuple) { + this.codec = tuple.codec; + this.input = tuple.input; + this.decodedValue = tuple.decodedValue; + this.encodeImmune = tuple.encodeImmune; + } + + /** Checks that the input value matches the result of the codec encoding the decoded value. */ + @Test + public void testEncodeCharacter() { + assertEquals(input, codec.encodeCharacter(encodeImmune, decodedValue)); + } + + /** Checks encoding the character as a String. + *
+ * If the decoded value is in the immunity list, the the decoded value should be returned from the encode call. + * Otherwise, input is expected as the return. + */ + @Test + public void testEncode() { + String expected = Arrays.asList(encodeImmune).contains(decodedValue) ? decodedValue.toString() : input; + assertEquals(expected, codec.encode(encodeImmune, decodedValue.toString())); + } + + /** Checks that decoding the input value yields the decodedValue.*/ + @Test + public void testDecode() { + assertEquals(decodedValue.toString(), codec.decode(input)); + } + + /** Checks that the encoded input String is correctly decoded to the single decodedValue character reference.*/ + @Test + public void testDecodePushbackSequence() { + assertEquals(decodedValue, codec.decodeCharacter(new PushbackString(input))); + } + +} diff --git a/src/test/java/org/owasp/esapi/codecs/abstraction/AbstractCodecStringTest.java b/src/test/java/org/owasp/esapi/codecs/abstraction/AbstractCodecStringTest.java new file mode 100644 index 000000000..b3a8b9a95 --- /dev/null +++ b/src/test/java/org/owasp/esapi/codecs/abstraction/AbstractCodecStringTest.java @@ -0,0 +1,82 @@ +/** + * 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-2018 - 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.codecs.abstraction; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.owasp.esapi.codecs.Codec; + + +/** + * Abstract parameterized test case meant to assist with verifying String api of a Codec implementation. + *
+ * Sub-classes are expected to provide instances of {@link CodecStringTestTuple} to this instance. + *
+ * For better test naming output specify {@link CodecStringTestTuple#description} and use @Parameters (name="{0}"), + * where '0' is the index that the CodecStringTestTuple reference appears in the constructor. + */ +@RunWith(Parameterized.class) +public abstract class AbstractCodecStringTest { + + protected static class CodecStringTestTuple { + /** Codec reference to be tested.*/ + public Codec codec; + /** Set of characters that should be considered 'immune' from decoding processes.*/ + public char[] encodeImmune; + /** A String representing a contextually encoded String.*/ + public String input; + /** The decoded representation of the input value.*/ + public String decodedValue; + /** Optional field to override the toString value of this tuple. */ + public String description; + + /**Default public constructor.*/ + public CodecStringTestTuple() { /* No Op*/ } + + /** {@inheritDoc}*/ + @Override + public String toString() { + return description != null ? description : codec.getClass().getSimpleName() + " "+input; + } + } + private final Codec codec; + private final String input; + private final char[] encodeImmune; + private final String decodedValue; + + public AbstractCodecStringTest(CodecStringTestTuple tuple) { + this.codec = tuple.codec; + this.input = tuple.input; + this.decodedValue = tuple.decodedValue; + this.encodeImmune = tuple.encodeImmune; + } + + + /** Checks that when the input is decoded using the specified codec, that the return matches the expected decoded value.*/ + @Test + public void testDecode() { + assertEquals(decodedValue, codec.decode(input)); + } + + /** Checks that when the decoded value is encoded (using immunity), that the return matches the provided input.*/ + @Test + public void testEncode() { + assertEquals(input, codec.encode(encodeImmune, decodedValue)); + } + +} diff --git a/src/test/java/org/owasp/esapi/codecs/percent/PercentCodecCharacterTest.java b/src/test/java/org/owasp/esapi/codecs/percent/PercentCodecCharacterTest.java new file mode 100644 index 000000000..f80f771c0 --- /dev/null +++ b/src/test/java/org/owasp/esapi/codecs/percent/PercentCodecCharacterTest.java @@ -0,0 +1,108 @@ +/** + * 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-2018 - 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.codecs.percent; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.owasp.esapi.codecs.percent.PercentCodecStringTest.PERCENT_CODEC_IMMUNE; + +import java.util.ArrayList; +import java.util.Collection; + +import org.junit.Test; +import org.junit.runners.Parameterized.Parameters; +import org.owasp.esapi.codecs.PercentCodec; +import org.owasp.esapi.codecs.PushbackString; +import org.owasp.esapi.codecs.abstraction.AbstractCodecCharacterTest; + +/** + * Codec validation focused on the PercentCodec Character-based api. + * + */ +public class PercentCodecCharacterTest extends AbstractCodecCharacterTest { + @Parameters(name = "{0}") + public static Collection buildTests() { + Collection tests = new ArrayList<>(); + Collection tuples = new ArrayList<>(); + + tuples.add(newTuple("%3C", Character.valueOf('<'))); + + tuples.add(newTuple("%00", Character.MIN_VALUE)); + tuples.add(newTuple("%3D", '=')); + tuples.add(newTuple("%26", '&')); + + for (char c : PERCENT_CODEC_IMMUNE) { + tuples.add(newTuple(Character.toString(c), c)); + } + + for (CodecCharacterTestTuple tuple : tuples) { + tests.add(new Object[] { tuple }); + } + + return tests; + } + + private static CodecCharacterTestTuple newTuple(String encodedInput, Character decoded) { + CodecCharacterTestTuple tuple = new CodecCharacterTestTuple(); + tuple.codec = new PercentCodec(); + tuple.encodeImmune = PERCENT_CODEC_IMMUNE; + tuple.decodedValue = decoded; + tuple.input = encodedInput; + + return tuple; + } + + public PercentCodecCharacterTest(CodecCharacterTestTuple tuple) { + super(tuple); + } + + @Override + @Test + public void testDecodePushbackSequence() { + // check duplicated from PushbackSequence handling in PercentCodec. + boolean inputIsEncoded = input.startsWith("%"); + + if (inputIsEncoded) { + assertInputIsDecodedToValue(); + } else { + assertInputIsDecodedToNull(); + } + } + + /** + * tests that when Input is decoded through a PushbackString that the decodedValue reference is returned and that + * the PushbackString index has incremented. + */ + @SuppressWarnings("unchecked") + private void assertInputIsDecodedToValue() { + PushbackString pbs = new PushbackString(input); + int startIndex = pbs.index(); + assertEquals(decodedValue, codec.decodeCharacter(pbs)); + assertTrue(startIndex < pbs.index()); + } + + /** + * tests that when Input is decoded through a PushbackString that null is returned and that the PushbackString index + * remains unchanged. + */ + @SuppressWarnings("unchecked") + private void assertInputIsDecodedToNull() { + PushbackString pbs = new PushbackString(input); + int startIndex = pbs.index(); + assertEquals(null, codec.decodeCharacter(pbs)); + assertEquals(startIndex, pbs.index()); + } + +} diff --git a/src/test/java/org/owasp/esapi/codecs/percent/PercentCodecKnownIssuesTest.java b/src/test/java/org/owasp/esapi/codecs/percent/PercentCodecKnownIssuesTest.java new file mode 100644 index 000000000..215070837 --- /dev/null +++ b/src/test/java/org/owasp/esapi/codecs/percent/PercentCodecKnownIssuesTest.java @@ -0,0 +1,56 @@ +/** + * 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-2018 - 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.codecs.percent; + +import static org.junit.Assert.assertEquals; +import static org.owasp.esapi.codecs.percent.PercentCodecStringTest.PERCENT_CODEC_IMMUNE; + +import org.junit.Test; +import org.owasp.esapi.codecs.PercentCodec; +/** + * This test class holds the proof of known deficiencies, inconsistencies, or bugs with the PercentCodec implementation. + *
+ * The intent is that when that functionality is corrected, these tests should break. That should hopefully encourage + * the author to move the test to an appropriate Test file and update the functionality to a working expectation. + */ +public class PercentCodecKnownIssuesTest { + + private PercentCodec codec = new PercentCodec(); + + /** + * PercentCodec has not been fully implemented for codepoint support, which handles UTF16 characters (based on my current understanding). + * As such, the encoding/decoding of UTF16 will not function as desired through the codec implementation. + *
+ * When the functionality is corrected this test will break. At that point UTF16 tests should be added to {@link PercentCodecStringTest} and {@link PercentCodecCharacterTest}. + */ + @Test + public void failsUTF16Conversions() { + //This should be 195 + int incorrectDecodeExpect = 196; + + char[] encodeImmune = PERCENT_CODEC_IMMUNE; + String decodedValue = ""+(char) 0x100; + String input = "%C4%80"; + + String actualDecodeChar = codec.decode(input); + int actualChar = (int)actualDecodeChar.charAt(0); + + assertEquals(incorrectDecodeExpect, actualChar); + + //This works as expected. + assertEquals(input, codec.encode(encodeImmune, decodedValue)); + } + +} diff --git a/src/test/java/org/owasp/esapi/codecs/percent/PercentCodecStringTest.java b/src/test/java/org/owasp/esapi/codecs/percent/PercentCodecStringTest.java new file mode 100644 index 000000000..57277b1d2 --- /dev/null +++ b/src/test/java/org/owasp/esapi/codecs/percent/PercentCodecStringTest.java @@ -0,0 +1,95 @@ +/** + * 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-2018 - 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.codecs.percent; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.junit.runners.Parameterized.Parameters; +import org.owasp.esapi.codecs.PercentCodec; +import org.owasp.esapi.codecs.abstraction.AbstractCodecStringTest; + +/** + * Codec validation focused on the PercentCodec String-based api. + * + */ +public class PercentCodecStringTest extends AbstractCodecStringTest { + public static final char[] PERCENT_CODEC_IMMUNE; + + static { + /* + * The percent codec contains a unique immune character set which include letters and numbers that will not be transformed. + * + * It is being replicated here to allow the test to reasonably expect the correct state back. + */ + List immune = new ArrayList<>(); + // 65 - 90 (capital letters in ASCII) 97 - 122 lower case 48 - 57 digits + //numbers + for (int index = 48 ; index < 58; index ++) { + immune.add((char)index); + } + //letters + for (int index = 65 ; index < 91; index ++) { + Character capsChar = (char)index; + immune.add(capsChar); + immune.add(Character.toLowerCase(capsChar)); + } + + PERCENT_CODEC_IMMUNE = new char[immune.size()]; + for (int index = 0; index < immune.size(); index++) { + PERCENT_CODEC_IMMUNE[index] = immune.get(index).charValue(); + } + } + + @Parameters(name = "{0}") + public static Collection buildTests() { + Collection tests = new ArrayList<>(); + List tuples = new ArrayList<>(); + + tuples.add(newTuple("%3C", "<")); + tuples.add(newTuple("%00", Character.MIN_VALUE)); + tuples.add(newTuple("%3D", '=')); + tuples.add(newTuple("%26", '&')); + + for (char c : PERCENT_CODEC_IMMUNE) { + tuples.add(newTuple(Character.toString(c), c)); + } + + for (CodecStringTestTuple tuple : tuples) { + tests.add(new Object[] { tuple }); + } + + return tests; + } + + private static CodecStringTestTuple newTuple(String input, Object decoded) { + CodecStringTestTuple tuple = new CodecStringTestTuple(); + tuple.codec = new PercentCodec(); + tuple.encodeImmune = PERCENT_CODEC_IMMUNE; + tuple.decodedValue = decoded.toString(); + tuple.input = input; + + return tuple; + } + + /** + * @param tuple + */ + public PercentCodecStringTest(CodecStringTestTuple tuple) { + super(tuple); + } + +} diff --git a/src/test/java/org/owasp/esapi/codecs/ref/EncodingPatternPreservationTest.java b/src/test/java/org/owasp/esapi/codecs/ref/EncodingPatternPreservationTest.java new file mode 100644 index 000000000..59701c58f --- /dev/null +++ b/src/test/java/org/owasp/esapi/codecs/ref/EncodingPatternPreservationTest.java @@ -0,0 +1,79 @@ +package org.owasp.esapi.codecs.ref; + +import java.util.regex.Pattern; + +import org.junit.Test; + +import static org.junit.Assert.*; + +public class EncodingPatternPreservationTest { + + @Test + public void testReplaceAndRestore() { + Pattern numberRegex = Pattern.compile("(ABC)"); + EncodingPatternPreservation epp = new EncodingPatternPreservation(numberRegex); + String origStr = "12 ABC 34 DEF 56 G 7"; + String replacedStr = epp.captureAndReplaceMatches(origStr); + + assertEquals("12 EncodingPatternPreservation 34 DEF 56 G 7", replacedStr); + + String restored = epp.restoreOriginalContent(replacedStr); + assertEquals(origStr, restored); + } + + @Test + public void testReplaceMultipleAndRestore() { + Pattern numberRegex = Pattern.compile("(ABC)"); + EncodingPatternPreservation epp = new EncodingPatternPreservation(numberRegex); + String origStr = "12 ABC 34 ABC 56 G 7 ABC8"; + String replacedStr = epp.captureAndReplaceMatches(origStr); + + assertEquals("12 EncodingPatternPreservation 34 EncodingPatternPreservation 56 G 7 EncodingPatternPreservation8", replacedStr); + + String restored = epp.restoreOriginalContent(replacedStr); + assertEquals(origStr, restored); + } + + @Test + public void testSetMarker() { + Pattern numberRegex = Pattern.compile("(ABC)"); + EncodingPatternPreservation epp = new EncodingPatternPreservation(numberRegex); + epp.setReplacementMarker(EncodingPatternPreservationTest.class.getSimpleName()); + + String origStr = "12 ABC 34 DEF 56 G 7"; + String replacedStr = epp.captureAndReplaceMatches(origStr); + + assertEquals("12 EncodingPatternPreservationTest 34 DEF 56 G 7", replacedStr); + + String restored = epp.restoreOriginalContent(replacedStr); + assertEquals(origStr, restored); + } + + @Test (expected = IllegalStateException.class) + public void testSetMarkerExceptionNoReset() { + Pattern numberRegex = Pattern.compile("(ABC)"); + EncodingPatternPreservation epp = new EncodingPatternPreservation(numberRegex); + String origStr = "12 ABC 34 DEF 56 G 7"; + epp.captureAndReplaceMatches(origStr); + //This allows the + case to be illustrated + epp.reset(); + + //And the exception case. + epp.captureAndReplaceMatches(origStr); + epp.setReplacementMarker(EncodingPatternPreservationTest.class.getSimpleName()); + } + + @Test (expected = IllegalStateException.class) + public void testReplaceExceptionNoReset() { + Pattern numberRegex = Pattern.compile("(ABC)"); + EncodingPatternPreservation epp = new EncodingPatternPreservation(numberRegex); + String origStr = "12 ABC 34 DEF 56 G 7"; + epp.captureAndReplaceMatches(origStr); + //This allows the + case to be illustrated + epp.reset(); + + //And the exception case. + epp.captureAndReplaceMatches(origStr); + epp.captureAndReplaceMatches(origStr); + } +} diff --git a/src/test/java/org/owasp/esapi/configuration/EsapiPropertyManagerTest.java b/src/test/java/org/owasp/esapi/configuration/EsapiPropertyManagerTest.java new file mode 100644 index 000000000..507f33ce1 --- /dev/null +++ b/src/test/java/org/owasp/esapi/configuration/EsapiPropertyManagerTest.java @@ -0,0 +1,441 @@ +package org.owasp.esapi.configuration; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertNotSame; +import static junit.framework.Assert.fail; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; + +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.configuration.consts.EsapiConfiguration; +import org.owasp.esapi.errors.ConfigurationException; + +public class EsapiPropertyManagerTest { + + private static String propFilename1; + private static String propFilename2; + private static String xmlFilename1; + private static String xmlFilename2; + private static final String noSuchFile = "/invalidDir/noSubDir/nosuchFile.xml"; + + private EsapiPropertyManager testPropertyManager; + private static String DEVTEAM_CFG = ""; + private static String OPSTEAM_CFG = ""; + + @BeforeClass + public static void captureEsapiConfigurations() { + DEVTEAM_CFG = System.getProperty(EsapiConfiguration.DEVTEAM_ESAPI_CFG.getConfigName(),""); + OPSTEAM_CFG = System.getProperty(EsapiConfiguration.OPSTEAM_ESAPI_CFG.getConfigName(),""); + } + + @AfterClass + public static void restoreEsapiConfigurations() { + System.setProperty(EsapiConfiguration.DEVTEAM_ESAPI_CFG.getConfigName(), DEVTEAM_CFG); + System.setProperty(EsapiConfiguration.OPSTEAM_ESAPI_CFG.getConfigName(), OPSTEAM_CFG); + } + + + @Before + public void init() { + System.setProperty(EsapiConfiguration.DEVTEAM_ESAPI_CFG.getConfigName(), ""); + System.setProperty(EsapiConfiguration.OPSTEAM_ESAPI_CFG.getConfigName(), ""); + propFilename1 = "src" + File.separator + "test" + File.separator + "resources" + File.separator + + "esapi" + File.separator + "ESAPI-test.properties"; + propFilename2 = "src" + File.separator + "test" + File.separator + "resources" + File.separator + + "esapi" + File.separator + "ESAPI-test-2.properties"; + xmlFilename1 = "src" + File.separator + "test" + File.separator + "resources" + File.separator + + "esapi" + File.separator + "ESAPI-test.xml"; + xmlFilename2 = "src" + File.separator + "test" + File.separator + "resources" + File.separator + + "esapi" + File.separator + "ESAPI-test-2.xml"; + + } + + @Test + public void testPropertyManagerInitialized() { + // given + System.setProperty(EsapiConfiguration.DEVTEAM_ESAPI_CFG.getConfigName(), propFilename1); + System.setProperty(EsapiConfiguration.OPSTEAM_ESAPI_CFG.getConfigName(), propFilename2); + + // when + try { + testPropertyManager = new EsapiPropertyManager(); + } catch (IOException e) { + fail(e.getMessage()); + } + + // then + assertNotNull(testPropertyManager.loaders); + assertNotSame(0, testPropertyManager.loaders.size()); + } + + @Test + public void testStringPropFoundInLoader() { + // given + System.setProperty(EsapiConfiguration.DEVTEAM_ESAPI_CFG.getConfigName(), xmlFilename1); + String propertyKey = "string_property"; + String expectedPropertyValue = "test_string_property"; + + // when + try { + testPropertyManager = new EsapiPropertyManager(); + } catch (IOException e) { + fail(e.getMessage()); + } + String propertyValue = testPropertyManager.getStringProp(propertyKey); + + // then + assertEquals(expectedPropertyValue, propertyValue); + } + + @Test + public void testStringPropertyLoadedFromFileWithHigherPriority() { + // given + System.setProperty(EsapiConfiguration.DEVTEAM_ESAPI_CFG.getConfigName(), propFilename1); + System.setProperty(EsapiConfiguration.OPSTEAM_ESAPI_CFG.getConfigName(), xmlFilename2); + + String propertyKey = "string_property"; + String expectedValue = "test_string_property_2"; + + // when + try { + testPropertyManager = new EsapiPropertyManager(); + } catch (IOException e) { + fail(e.getMessage()); + } + String propertyValue = testPropertyManager.getStringProp(propertyKey); + + // then + assertEquals(expectedValue, propertyValue); + } + + @Test + public void testStringPropertyLoadedFromPropFileWithHigherPriority() { + // given + System.setProperty(EsapiConfiguration.DEVTEAM_ESAPI_CFG.getConfigName(), propFilename1); + System.setProperty(EsapiConfiguration.OPSTEAM_ESAPI_CFG.getConfigName(), propFilename2); + String propertyKey = "string_property"; + String expectedValue = "test_string_property_2"; + + // when + try { + testPropertyManager = new EsapiPropertyManager(); + } catch (IOException e) { + fail(e.getMessage()); + } + String propertyValue = testPropertyManager.getStringProp(propertyKey); + + // then + assertEquals(expectedValue, propertyValue); + } + + @Test + public void testStringPropertyLoadedFromXmlFileWithHigherPriority() { + // given + System.setProperty(EsapiConfiguration.DEVTEAM_ESAPI_CFG.getConfigName(), xmlFilename1); + System.setProperty(EsapiConfiguration.OPSTEAM_ESAPI_CFG.getConfigName(), xmlFilename2); + String propertyKey = "string_property"; + String expectedValue = "test_string_property_2"; + + // when + try { + testPropertyManager = new EsapiPropertyManager(); + } catch (IOException e) { + fail(e.getMessage()); + } + String propertyValue = testPropertyManager.getStringProp(propertyKey); + + // then + assertEquals(expectedValue, propertyValue); + } + + + @Test(expected = ConfigurationException.class) + public void testStringPropertyNotFoundByLoaderAndThrowException() { + // given + System.setProperty(EsapiConfiguration.DEVTEAM_ESAPI_CFG.getConfigName(), propFilename1); + String propertyKey = "non.existing.property"; + + // when + try { + testPropertyManager = new EsapiPropertyManager(); + } catch (IOException e) { + fail(e.getMessage()); + } + testPropertyManager.getStringProp(propertyKey); + + // then expect exception + } + + @Test + public void testIntPropFoundInLoader() { + // given + System.setProperty(EsapiConfiguration.DEVTEAM_ESAPI_CFG.getConfigName(), xmlFilename1); + String propertyKey = "int_property"; + int expectedPropertyValue = 5; + + // when + try { + testPropertyManager = new EsapiPropertyManager(); + } catch (IOException e) { + fail(e.getMessage()); + } + int propertyValue = testPropertyManager.getIntProp(propertyKey); + + // then + assertEquals(expectedPropertyValue, propertyValue); + } + + @Test + public void testIntPropertyLoadedFromFileWithHigherPriority() { + // given + System.setProperty(EsapiConfiguration.DEVTEAM_ESAPI_CFG.getConfigName(), propFilename1); + System.setProperty(EsapiConfiguration.OPSTEAM_ESAPI_CFG.getConfigName(), xmlFilename2); + String propertyKey = "int_property"; + int expectedValue = 52; + + // when + try { + testPropertyManager = new EsapiPropertyManager(); + } catch (IOException e) { + fail(e.getMessage()); + } + int propertyValue = testPropertyManager.getIntProp(propertyKey); + + // then + assertEquals(expectedValue, propertyValue); + } + + @Test + public void testIntPropertyLoadedFromPropFileWithHigherPriority() { + // given + System.setProperty(EsapiConfiguration.DEVTEAM_ESAPI_CFG.getConfigName(), propFilename1); + System.setProperty(EsapiConfiguration.OPSTEAM_ESAPI_CFG.getConfigName(), propFilename2); + String propertyKey = "int_property"; + int expectedValue = 52; // value from ESAPI-test-2.properties file + + // when + try { + testPropertyManager = new EsapiPropertyManager(); + } catch (IOException e) { + fail(e.getMessage()); + } + int propertyValue = testPropertyManager.getIntProp(propertyKey); + + // then + assertEquals(expectedValue, propertyValue); + } + + @Test + public void testIntPropertyLoadedFromXmlFileWithHigherPriority() { + // given + System.setProperty(EsapiConfiguration.DEVTEAM_ESAPI_CFG.getConfigName(), xmlFilename1); + System.setProperty(EsapiConfiguration.OPSTEAM_ESAPI_CFG.getConfigName(), xmlFilename2); + String propertyKey = "int_property"; + int expectedValue = 52; + + // when + try { + testPropertyManager = new EsapiPropertyManager(); + } catch (IOException e) { + fail(e.getMessage()); + } + int propertyValue = testPropertyManager.getIntProp(propertyKey); + + // then + assertEquals(expectedValue, propertyValue); + } + + + @Test(expected = ConfigurationException.class) + public void testIntPropertyNotFoundByLoaderAndThrowException() { + // given + String propertyKey = "non.existing.property"; + + // when + try { + testPropertyManager = new EsapiPropertyManager(); + } catch (IOException e) { + fail(e.getMessage()); + } + testPropertyManager.getIntProp(propertyKey); + + // then expect exception + } + + @Test + public void testBooleanPropFoundInLoader() { + // given + System.setProperty(EsapiConfiguration.DEVTEAM_ESAPI_CFG.getConfigName(), xmlFilename1); + String propertyKey = "boolean_property"; + boolean expectedPropertyValue = true; + + // when + try { + testPropertyManager = new EsapiPropertyManager(); + } catch (IOException e) { + fail(e.getMessage()); + } + boolean propertyValue = testPropertyManager.getBooleanProp(propertyKey); + + // then + assertEquals(expectedPropertyValue, propertyValue); + } + + @Test(expected = ConfigurationException.class) + public void testBooleanPropertyNotFoundByLoaderAndThrowException() { + // given + String propertyKey = "non.existing.property"; + + // when + try { + testPropertyManager = new EsapiPropertyManager(); + } catch (IOException e) { + fail(e.getMessage()); + } + testPropertyManager.getBooleanProp(propertyKey); + + // then expect exception + } + + @Test + public void testByteArrayPropFoundInLoader() { + // given + System.setProperty(EsapiConfiguration.DEVTEAM_ESAPI_CFG.getConfigName(), propFilename1); + String propertyKey = "string_property"; + byte[] expectedValue = new byte[0]; + try { + expectedValue = ESAPI.encoder().decodeFromBase64("test_string_property"); + } catch (IOException e) { + fail(e.getMessage()); + } + + // when + try { + testPropertyManager = new EsapiPropertyManager(); + } catch (IOException e) { + fail(e.getMessage()); + } + byte[] propertyValue = testPropertyManager.getByteArrayProp(propertyKey); + + // then + assertEquals(expectedValue, propertyValue); + } + + @Test + public void testByteArrayPropertyLoadedFromFileWithHigherPriority() { + // given + System.setProperty(EsapiConfiguration.DEVTEAM_ESAPI_CFG.getConfigName(), propFilename1); + System.setProperty(EsapiConfiguration.OPSTEAM_ESAPI_CFG.getConfigName(), xmlFilename2); + String propertyKey = "string_property"; + byte[] expectedValue = new byte[0]; + try { + expectedValue = ESAPI.encoder().decodeFromBase64("test_string_property_2"); + } catch (IOException e) { + fail(e.getMessage()); + } + + // when + try { + testPropertyManager = new EsapiPropertyManager(); + } catch (IOException e) { + fail(e.getMessage()); + } + byte[] propertyValue = testPropertyManager.getByteArrayProp(propertyKey); + + // then + assertEquals(expectedValue, propertyValue); + } + + @Test + public void testByteArrayPropertyLoadedFromPropFileWithHigherPriority() { + // given + System.setProperty(EsapiConfiguration.DEVTEAM_ESAPI_CFG.getConfigName(), propFilename1); + System.setProperty(EsapiConfiguration.OPSTEAM_ESAPI_CFG.getConfigName(), propFilename2); + String propertyKey = "string_property"; + byte[] expectedValue = new byte[0]; + try { + expectedValue = ESAPI.encoder().decodeFromBase64("test_string_property_2"); + } catch (IOException e) { + fail(e.getMessage()); + } + + // when + try { + testPropertyManager = new EsapiPropertyManager(); + } catch (IOException e) { + fail(e.getMessage()); + } + byte[] propertyValue = testPropertyManager.getByteArrayProp(propertyKey); + + // then + assertEquals(expectedValue, propertyValue); + } + + @Test + public void testByteArrayPropertyLoadedFromXmlFileWithHigherPriority() { + // given + System.setProperty(EsapiConfiguration.DEVTEAM_ESAPI_CFG.getConfigName(), xmlFilename1); + System.setProperty(EsapiConfiguration.OPSTEAM_ESAPI_CFG.getConfigName(), xmlFilename2); + String propertyKey = "string_property"; + byte[] expectedValue = new byte[0]; + try { + expectedValue = ESAPI.encoder().decodeFromBase64("test_string_property_2"); + } catch (IOException e) { + fail(e.getMessage()); + } + + // when + try { + testPropertyManager = new EsapiPropertyManager(); + } catch (IOException e) { + fail(e.getMessage()); + } + byte[] propertyValue = testPropertyManager.getByteArrayProp(propertyKey); + + // then + assertEquals(expectedValue, propertyValue); + } + + @Test(expected = ConfigurationException.class) + public void testByteArrayPropertyNotFoundByLoaderAndThrowException() { + // given + String propertyKey = "non.existing.property"; + + // when + try { + testPropertyManager = new EsapiPropertyManager(); + } catch (IOException e) { + fail(e.getMessage()); + } + testPropertyManager.getByteArrayProp(propertyKey); + + // then expect exception + } + + + @Test + public void testExpectFileNotFoundException() { + // given + System.setProperty(EsapiConfiguration.DEVTEAM_ESAPI_CFG.getConfigName(), noSuchFile); + + // when + try { + testPropertyManager = new EsapiPropertyManager(); + } catch (IOException e) { + if ( e instanceof FileNotFoundException ) { + return; + } else { + fail("testExpectFileNotFoundException(): Was expecting FileNotFoundException for IOException. Exception:" + e); + } + } + + fail("Did not throw expected IOException for property file " + noSuchFile); + } +} diff --git a/src/test/java/org/owasp/esapi/configuration/StandardEsapiPropertyLoaderTest.java b/src/test/java/org/owasp/esapi/configuration/StandardEsapiPropertyLoaderTest.java new file mode 100644 index 000000000..080644642 --- /dev/null +++ b/src/test/java/org/owasp/esapi/configuration/StandardEsapiPropertyLoaderTest.java @@ -0,0 +1,359 @@ +package org.owasp.esapi.configuration; + + +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.configuration.consts.EsapiConfiguration; +import org.owasp.esapi.errors.ConfigurationException; + +import java.io.File; +import java.io.IOException; + +import static junit.framework.Assert.*; + +public class StandardEsapiPropertyLoaderTest { + + private static String filename; + private static int priority; + + private StandardEsapiPropertyLoader testPropertyLoader; + + private static String DEVTEAM_CFG = ""; + private static String OPSTEAM_CFG = ""; + + @BeforeClass + public static void captureEsapiConfigurations() { + DEVTEAM_CFG = System.getProperty(EsapiConfiguration.DEVTEAM_ESAPI_CFG.getConfigName(),""); + OPSTEAM_CFG = System.getProperty(EsapiConfiguration.OPSTEAM_ESAPI_CFG.getConfigName(),""); + } + + @AfterClass + public static void restoreEsapiConfigurations() { + System.setProperty(EsapiConfiguration.DEVTEAM_ESAPI_CFG.getConfigName(), DEVTEAM_CFG); + System.setProperty(EsapiConfiguration.OPSTEAM_ESAPI_CFG.getConfigName(), OPSTEAM_CFG); + } + + + @Before + public void init() { + System.setProperty(EsapiConfiguration.DEVTEAM_ESAPI_CFG.getConfigName(), ""); + System.setProperty(EsapiConfiguration.OPSTEAM_ESAPI_CFG.getConfigName(), ""); + filename = "src" + File.separator + "test" + File.separator + "resources" + File.separator + + "esapi" + File.separator + "ESAPI-test.properties"; + priority = 1; + } + + @Test + public void testPropertiesLoaded() { + // when + try { + testPropertyLoader = new StandardEsapiPropertyLoader(filename, priority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + + // then + assertFalse(testPropertyLoader.properties.isEmpty()); + } + + @Test + public void testPriority() { + // given + int expectedValue = 1; + + // when + try { + testPropertyLoader = new StandardEsapiPropertyLoader(filename, priority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + int value = testPropertyLoader.priority(); + + // then + assertEquals(expectedValue, value); + } + + @Test + public void testLoadersAreEqual() { + // given + int expectedValue = 0; + StandardEsapiPropertyLoader otherPropertyLoader = null; + + // when + try { + testPropertyLoader = new StandardEsapiPropertyLoader(filename, priority); + otherPropertyLoader = new StandardEsapiPropertyLoader(filename, priority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + int value = testPropertyLoader.compareTo(otherPropertyLoader); + + // then + assertEquals(expectedValue, value); + } + + @Test + public void testCompareWithOtherLoaderWithHigherPriority() { + // given + int expectedValue = -1; + int higherPriority = 2; + StandardEsapiPropertyLoader otherPropertyLoader = null; + + // when + try { + testPropertyLoader = new StandardEsapiPropertyLoader(filename, priority); + otherPropertyLoader = new StandardEsapiPropertyLoader(filename, higherPriority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + int value = testPropertyLoader.compareTo(otherPropertyLoader); + + // then + assertEquals(expectedValue, value); + } + + @Test + public void testCompareWithOtherLoaderWithLowerPriority() { + // given + int expectedValue = 1; + int lowerPriority = 0; + StandardEsapiPropertyLoader otherPropertyLoader = null; + + // when + try { + testPropertyLoader = new StandardEsapiPropertyLoader(filename, priority); + otherPropertyLoader = new StandardEsapiPropertyLoader(filename, lowerPriority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + int value = testPropertyLoader.compareTo(otherPropertyLoader); + + // then + assertEquals(expectedValue, value); + } + + @Test + public void testGetIntProp() { + // given + String propertyKey = "int_property"; + + // when + try { + testPropertyLoader = new StandardEsapiPropertyLoader(filename, priority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + int propertyValue = testPropertyLoader.getIntProp(propertyKey); + + // then + assertEquals(5, propertyValue); + } + + @Test(expected = ConfigurationException.class) + public void testIntPropertyNotFound() throws ConfigurationException { + // given + String propertyKey = "non-existing-key"; + + // when + try { + testPropertyLoader = new StandardEsapiPropertyLoader(filename, priority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + testPropertyLoader.getIntProp(propertyKey); + + // then expect exception + } + + @Test(expected = ConfigurationException.class) + public void testIncorrectIntPropertyType() { + // given + String key = "invalid_int_property"; + + // when + try { + testPropertyLoader = new StandardEsapiPropertyLoader(filename, priority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + testPropertyLoader.getIntProp(key); + + // then expect exception + } + + @Test + public void testGetStringProp() { + // given + String propertyKey = "string_property"; + String expectedValue = "test_string_property"; + + // when + try { + testPropertyLoader = new StandardEsapiPropertyLoader(filename, priority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + String propertyValue = testPropertyLoader.getStringProp(propertyKey); + + // then + assertEquals(expectedValue, propertyValue); + } + + @Test(expected = ConfigurationException.class) + public void testStringPropertyNotFound() throws ConfigurationException { + // given + String propertyKey = "non-existing-key"; + + // when + try { + testPropertyLoader = new StandardEsapiPropertyLoader(filename, priority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + testPropertyLoader.getStringProp(propertyKey); + + // then expect exception + } + + @Test + public void testGetBooleanProp() { + // given + String filename = "src" + File.separator + "test" + File.separator + "resources" + File.separator + + "esapi" + File.separator + "ESAPI-test.properties"; + int priority = 1; + String propertyKey = "boolean_property"; + boolean expectedValue = true; + + // when + try { + testPropertyLoader = new StandardEsapiPropertyLoader(filename, priority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + boolean value = testPropertyLoader.getBooleanProp(propertyKey); + + // then + assertEquals(expectedValue, value); + } + + @Test + public void testGetBooleanYesProperty() { + // given + String key = "boolean_yes_property"; + boolean expectedValue = true; + + // when + try { + testPropertyLoader = new StandardEsapiPropertyLoader(filename, priority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + boolean value = testPropertyLoader.getBooleanProp(key); + + // then + assertEquals(expectedValue, value); + } + + @Test + public void testGetBooleanNoProperty() { + // given + String key = "boolean_no_property"; + boolean expectedValue = false; + + // when + try { + testPropertyLoader = new StandardEsapiPropertyLoader(filename, priority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + boolean value = testPropertyLoader.getBooleanProp(key); + + // then + assertEquals(expectedValue, value); + } + + @Test(expected = ConfigurationException.class) + public void testBooleanPropertyNotFound() throws ConfigurationException { + // given + String filename = "src" + File.separator + "test" + File.separator + "resources" + File.separator + + "esapi" + File.separator + "ESAPI-test.properties"; + int priority = 1; + String propertyKey = "non-existing-key"; + + // when + try { + testPropertyLoader = new StandardEsapiPropertyLoader(filename, priority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + testPropertyLoader.getBooleanProp(propertyKey); + + // then expect exception + } + + @Test(expected = ConfigurationException.class) + public void testIncorrectBooleanPropertyType() throws ConfigurationException { + // given + String key = "invalid_boolean_property"; + + // when + try { + testPropertyLoader = new StandardEsapiPropertyLoader(filename, priority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + testPropertyLoader.getBooleanProp(key); + + // then expect exception + } + + @Test + public void testGetByteArrayProp() { + // given + String filename = "src" + File.separator + "test" + File.separator + "resources" + File.separator + + "esapi" + File.separator + "ESAPI-test.properties"; + int priority = 1; + String propertyKey = "string_property"; + + byte[] expectedValue = new byte[0]; + try { + expectedValue = ESAPI.encoder().decodeFromBase64("test_string_property"); + } catch (IOException e) { + fail(e.getMessage()); + } + + // when + try { + testPropertyLoader = new StandardEsapiPropertyLoader(filename, priority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + byte[] value = testPropertyLoader.getByteArrayProp(propertyKey); + + // then + assertEquals(expectedValue, value); + } + + @Test(expected = ConfigurationException.class) + public void testByteArrayPropertyNotFound() throws ConfigurationException { + // given + String filename = "src" + File.separator + "test" + File.separator + "resources" + File.separator + + "esapi" + File.separator + "ESAPI-test.properties"; int priority = 1; + String propertyKey = "non-existing-key"; + + // when + try { + testPropertyLoader = new StandardEsapiPropertyLoader(filename, priority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + + testPropertyLoader.getByteArrayProp(propertyKey); + + // then expect exception + } + +} diff --git a/src/test/java/org/owasp/esapi/configuration/XmlEsapiPropertyLoaderTest.java b/src/test/java/org/owasp/esapi/configuration/XmlEsapiPropertyLoaderTest.java new file mode 100644 index 000000000..6aecec533 --- /dev/null +++ b/src/test/java/org/owasp/esapi/configuration/XmlEsapiPropertyLoaderTest.java @@ -0,0 +1,364 @@ +package org.owasp.esapi.configuration; + +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.configuration.consts.EsapiConfiguration; +import org.owasp.esapi.errors.ConfigurationException; + +import java.io.File; +import java.io.IOException; + +import static junit.framework.Assert.*; + +public class XmlEsapiPropertyLoaderTest { + + private static String filename; + private static int priority; + + private XmlEsapiPropertyLoader testPropertyLoader; + + private static String DEVTEAM_CFG = ""; + private static String OPSTEAM_CFG = ""; + + @BeforeClass + public static void captureEsapiConfigurations() { + DEVTEAM_CFG = System.getProperty(EsapiConfiguration.DEVTEAM_ESAPI_CFG.getConfigName(),""); + OPSTEAM_CFG = System.getProperty(EsapiConfiguration.OPSTEAM_ESAPI_CFG.getConfigName(),""); + } + + @AfterClass + public static void restoreEsapiConfigurations() { + System.setProperty(EsapiConfiguration.DEVTEAM_ESAPI_CFG.getConfigName(), DEVTEAM_CFG); + System.setProperty(EsapiConfiguration.OPSTEAM_ESAPI_CFG.getConfigName(), OPSTEAM_CFG); + } + + @Before + public void init() { + System.setProperty(EsapiConfiguration.DEVTEAM_ESAPI_CFG.getConfigName(), ""); + System.setProperty(EsapiConfiguration.OPSTEAM_ESAPI_CFG.getConfigName(), ""); + filename = "src" + File.separator + "test" + File.separator + "resources" + File.separator + + "esapi" + File.separator + "ESAPI-test.xml"; + priority = 1; + } + + @Test + public void testPropertiesLoaded() { + // when + try { + testPropertyLoader = new XmlEsapiPropertyLoader(filename, priority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + + // then + assertFalse(testPropertyLoader.properties.isEmpty()); + } + + @Test + public void testInvalidPropertyFile() { + // given - the file exists, but does not conform to the schema. + String invalidFilename = "src" + File.separator + "test" + File.separator + "resources" + File.separator + + "esapi" + File.separator + "ESAPI-test-invalid-content.xml"; + + // when + try { + testPropertyLoader = new XmlEsapiPropertyLoader(invalidFilename, priority); + } catch ( IOException iex ) { + // iex.printStackTrace(System.err); + fail("Caught unexpected IOException; exception was: " + iex); + } catch ( ConfigurationException cex) { + return; + } + + fail("Failed to catch expected ConfigurationException for invalid property file name: " + invalidFilename); + } + + @Test + public void testPriority() { + // given + int expectedValue = 1; + + // when + try { + testPropertyLoader = new XmlEsapiPropertyLoader(filename, priority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + int value = testPropertyLoader.priority(); + + // then + assertEquals(expectedValue, value); + } + + @Test + public void testLoadersAreEqual() { + // given + int expectedValue = 0; + StandardEsapiPropertyLoader otherPropertyLoader = null; + + // when + try { + testPropertyLoader = new XmlEsapiPropertyLoader(filename, priority); + otherPropertyLoader = new StandardEsapiPropertyLoader(filename, priority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + int value = testPropertyLoader.compareTo(otherPropertyLoader); + + // then + assertEquals(expectedValue, value); + } + + @Test + public void testCompareWithOtherLoaderWithHigherPriority() { + // given + int expectedValue = -1; + int higherPriority = 2; + StandardEsapiPropertyLoader otherPropertyLoader = null; + + // when + try { + testPropertyLoader = new XmlEsapiPropertyLoader(filename, priority); + otherPropertyLoader = new StandardEsapiPropertyLoader(filename, higherPriority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + int value = testPropertyLoader.compareTo(otherPropertyLoader); + + // then + assertEquals(expectedValue, value); + } + + @Test + public void testCompareWithOtherLoaderWithLowerPriority() { + // given + int expectedValue = 1; + int lowerPriority = 0; + StandardEsapiPropertyLoader otherPropertyLoader = null; + + // when + try { + testPropertyLoader = new XmlEsapiPropertyLoader(filename, priority); + otherPropertyLoader = new StandardEsapiPropertyLoader(filename, lowerPriority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + int value = testPropertyLoader.compareTo(otherPropertyLoader); + + // then + assertEquals(expectedValue, value); + } + + @Test + public void testGetIntProp() { + // given + String key = "int_property"; + int expectedValue = 5; + + // when + try { + testPropertyLoader = new XmlEsapiPropertyLoader(filename, priority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + int value = testPropertyLoader.getIntProp(key); + + // then + assertEquals(expectedValue, value); + } + + @Test(expected = ConfigurationException.class) + public void testIntPropertyNotFound() throws ConfigurationException { + // given + String key = "non-existing-key"; + + // when + try { + testPropertyLoader = new XmlEsapiPropertyLoader(filename, priority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + testPropertyLoader.getIntProp(key); + + // then expect exception + } + + @Test(expected = ConfigurationException.class) + public void testIncorrectIntPropertyType() { + // given + String key = "invalid_int_property"; + + // when + try { + testPropertyLoader = new XmlEsapiPropertyLoader(filename, priority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + testPropertyLoader.getIntProp(key); + + // then expect exception + } + + @Test + public void testGetStringProp() { + // given + String key = "string_property"; + String expectedValue = "test_string_property"; + + // when + try { + testPropertyLoader = new XmlEsapiPropertyLoader(filename, priority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + String value = testPropertyLoader.getStringProp(key); + + // then + assertEquals(expectedValue, value); + } + + @Test(expected = ConfigurationException.class) + public void testStringPropertyNotFound() throws ConfigurationException { + // given + String key = "non-existing-key"; + + // when + try { + testPropertyLoader = new XmlEsapiPropertyLoader(filename, priority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + testPropertyLoader.getStringProp(key); + + // then expect exception + } + + @Test + public void testGetBooleanProp() { + // given + String key = "boolean_property"; + boolean expectedValue = true; + + // when + try { + testPropertyLoader = new XmlEsapiPropertyLoader(filename, priority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + boolean value = testPropertyLoader.getBooleanProp(key); + + // then + assertEquals(expectedValue, value); + } + + @Test + public void testGetBooleanYesProperty() { + // given + String key = "boolean_yes_property"; + boolean expectedValue = true; + + // when + try { + testPropertyLoader = new XmlEsapiPropertyLoader(filename, priority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + boolean value = testPropertyLoader.getBooleanProp(key); + + // then + assertEquals(expectedValue, value); + } + + @Test + public void testGetBooleanNoProperty() { + // given + String key = "boolean_no_property"; + boolean expectedValue = false; + + // when + try { + testPropertyLoader = new XmlEsapiPropertyLoader(filename, priority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + boolean value = testPropertyLoader.getBooleanProp(key); + + // then + assertEquals(expectedValue, value); + } + + @Test(expected = ConfigurationException.class) + public void testBooleanPropertyNotFound() throws ConfigurationException { + // given + String key = "non-existing-key"; + + // when + try { + testPropertyLoader = new XmlEsapiPropertyLoader(filename, priority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + testPropertyLoader.getBooleanProp(key); + + // then expect exception + } + + @Test(expected = ConfigurationException.class) + public void testIncorrectBooleanPropertyType() throws ConfigurationException { + // given + String key = "invalid_boolean_property"; + + // when + try { + testPropertyLoader = new XmlEsapiPropertyLoader(filename, priority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + testPropertyLoader.getBooleanProp(key); + + // then expect exception + } + + @Test + public void testGetByteArrayProp() { + // given + String key = "string_property"; + byte[] expectedValue = new byte[0]; + try { + expectedValue = ESAPI.encoder().decodeFromBase64("test_string_property"); + } catch (IOException e) { + fail(e.getMessage()); + } + + // when + try { + testPropertyLoader = new XmlEsapiPropertyLoader(filename, priority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + byte[] value = testPropertyLoader.getByteArrayProp(key); + + // then + assertEquals(expectedValue, value); + } + + @Test(expected = ConfigurationException.class) + public void testByteArrayPropertyNotFound() throws ConfigurationException { + // given + String key = "non-existing-key"; + + // when + try { + testPropertyLoader = new XmlEsapiPropertyLoader(filename, priority); + } catch ( IOException e ) { + fail( e.getMessage() ); + } + testPropertyLoader.getByteArrayProp(key); + + // then expect exception + } + +} diff --git a/src/test/java/org/owasp/esapi/crypto/CipherSpecTest.java b/src/test/java/org/owasp/esapi/crypto/CipherSpecTest.java new file mode 100644 index 000000000..54c69a520 --- /dev/null +++ b/src/test/java/org/owasp/esapi/crypto/CipherSpecTest.java @@ -0,0 +1,271 @@ +package org.owasp.esapi.crypto; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import javax.crypto.Cipher; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.codecs.Hex; +import org.owasp.esapi.crypto.CipherSpec; + +/** JUnit test to test CipherSpec class. */ +public class CipherSpecTest extends TestCase { + + private Cipher dfltAESCipher = null; + private Cipher dfltECBCipher = null; // will be "AES/ECB/NoPadding"; + private Cipher dfltOtherCipher = null; + private CipherSpec cipherSpec = null; + private byte[] myIV = null; + + @Before public void setUp() throws Exception { + myIV = Hex.decode( "0x000102030405060708090a0b0c0d0e0f" ); // Any IV to test w/ will do. + + dfltAESCipher = Cipher.getInstance("AES"); + dfltECBCipher = Cipher.getInstance("AES/ECB/NoPadding"); + dfltOtherCipher = Cipher.getInstance("Blowfish/OFB8/PKCS5Padding"); + + assertTrue( dfltAESCipher != null ); + assertTrue( dfltECBCipher != null ); + assertTrue( dfltOtherCipher != null ); + + cipherSpec = new CipherSpec(dfltOtherCipher); + assertTrue( cipherSpec != null ); + } + + @After public void tearDown() throws Exception { + // none + } + + /** Test CipherSpec(String cipherXform, int keySize, int blockSize, final byte[] iv) */ + @Test public void testCipherSpecStringIntIntByteArray() { + + cipherSpec = new CipherSpec( "AES/CBC/NoPadding", 128, 8, myIV); + assertTrue( cipherSpec != null ); + cipherSpec = null; + boolean caughtException = false; + try { + // Invalid cipher xform -- empty + cipherSpec = new CipherSpec( "", 128, 8, myIV); + } catch( Throwable t ) { + caughtException = true; + } + assertTrue( caughtException && (cipherSpec == null) ); + caughtException = false; + try { + // Invalid cipher xform -- missing padding scheme + cipherSpec = new CipherSpec("AES/CBC", 128, 8, myIV); + } catch( Throwable t ) { + caughtException = true; + } + assertTrue( caughtException && (cipherSpec == null) ); + } + + /** CipherSpec(final Cipher cipher, int keySize) */ + @Test public void testCipherSpecCipherInt() { + cipherSpec = new CipherSpec(dfltOtherCipher, 112); + assertTrue( cipherSpec != null ); + assertTrue( cipherSpec.getCipherAlgorithm().equals("Blowfish")); + assertTrue( cipherSpec.getCipherMode().equals("OFB8")); + + cipherSpec = new CipherSpec(dfltAESCipher, 256); + assertTrue( cipherSpec != null ); + assertTrue( cipherSpec.getCipherAlgorithm().equals("AES")); + assertTrue( cipherSpec.getCipherMode().equals("ECB") ); + assertTrue( cipherSpec.getPaddingScheme().equals("NoPadding") ); + // System.out.println("testCipherSpecInt(): " + cipherSpec); + } + + /** Test CipherSpec(final byte[] iv) */ + @Test public void testCipherSpecByteArray() { + assertTrue( myIV != null ); + assertTrue( myIV.length > 0 ); + cipherSpec = new CipherSpec(myIV); + assertTrue( cipherSpec.getKeySize() == + ESAPI.securityConfiguration().getEncryptionKeyLength() ); + assertTrue( cipherSpec.getCipherTransformation().equals( + ESAPI.securityConfiguration().getCipherTransformation() ) ); + } + + /** Test CipherSpec() */ + @Test public void testCipherSpec() { + cipherSpec = new CipherSpec( dfltECBCipher ); + assertTrue( cipherSpec.getCipherTransformation().equals("AES/ECB/NoPadding") ); + assertTrue( cipherSpec.getIV() == null ); + + cipherSpec = new CipherSpec(dfltOtherCipher); + assertTrue( cipherSpec.getCipherMode().equals("OFB8") ); + } + + /** Test setCipherTransformation(String cipherXform) */ + @Test public void testSetCipherTransformation() { + cipherSpec = new CipherSpec(); + cipherSpec.setCipherTransformation("AlgName/Mode/Padding"); + cipherSpec.getCipherAlgorithm().equals("AlgName/Mode/Padding"); + + try { + // Don't use null here as compiling JUnit tests disables assertion + // checking so we get a NullPointerException here instead. + cipherSpec.setCipherTransformation(""); // Throws IllegalArgumentException + } catch (IllegalArgumentException e) { + assertTrue(true); // Doesn't work w/ @Test(expected=IllegalArgumentException.class) + } + } + + /** Test getCipherTransformation() */ + @Test public void testGetCipherTransformation() { + assertTrue( (new CipherSpec()).getCipherTransformation().equals("AES/CBC/PKCS5Padding") ); + } + + /** Test setKeySize() */ + @Test public void testSetKeySize() { + assertTrue( (new CipherSpec()).setKeySize(56).getKeySize() == 56 ); + } + + /** Test getKeySize() */ + @Test public void testGetKeySize() { + assertTrue( (new CipherSpec()).getKeySize() == + ESAPI.securityConfiguration().getEncryptionKeyLength() ); + } + + /** Test setBlockSize() */ + @Test public void testSetBlockSize() { + try { + cipherSpec.setBlockSize(0); // Throws IllegalArgumentException + } catch (IllegalArgumentException e) { + assertTrue(true); + } + try { + cipherSpec.setBlockSize(-1); // Throws IllegalArgumentException + } catch (IllegalArgumentException e) { + assertTrue(true); + } + assertTrue( cipherSpec.setBlockSize(4).getBlockSize() == 4 ); + } + + /** Test getBlockSize() */ + @Test public void testGetBlockSize() { + assertTrue( cipherSpec.getBlockSize() == 8 ); + } + + /** Test getCipherAlgorithm() */ + @Test public void testGetCipherAlgorithm() { + assertTrue( cipherSpec.getCipherAlgorithm().equals("Blowfish") ); + } + + /** Test getCipherMode */ + @Test public void testGetCipherMode() { + assertTrue( cipherSpec.getCipherMode().equals("OFB8") ); + } + + /** Test getPaddingScheme() */ + @Test public void testGetPaddingScheme() { + assertTrue( cipherSpec.getPaddingScheme().equals("PKCS5Padding") ); + } + + /** Test setIV() */ + @Test public void testSetIV() { + try { + // Test that ECB mode allows a null IV + cipherSpec = new CipherSpec(dfltECBCipher); + assertTrue( cipherSpec.getCipherMode().equals("ECB") ); + cipherSpec.setIV(null); + assertTrue(true); + } catch ( IllegalArgumentException e) { + assertFalse("Test failed; unexpected exception", false); + } + try { + // Test that CBC mode does allows a null IV + cipherSpec = new CipherSpec(dfltAESCipher); + cipherSpec.setIV(null); + assertFalse("Test failed; Expected exception not thrown", false); + } catch ( IllegalArgumentException e) { + assertTrue(true); + } + } + + /** Test requiresIV() */ + @Test public void testRequiresIV() { + assertTrue( (new CipherSpec(dfltECBCipher)).requiresIV() == false ); + cipherSpec = new CipherSpec(dfltAESCipher); + assertTrue( cipherSpec.getCipherMode().equals("ECB") ); + assertTrue( cipherSpec.requiresIV() == false ); + assertTrue( new CipherSpec(dfltOtherCipher).requiresIV() ); + } + + /** Test serialization */ + @Test public void testSerialization() { + String filename = "cipherspec.ser"; + File serializedFile = new File(filename); + boolean success = false; + try { + // Delete any old serialized file. If it fails, it's not + // a big deal. If we can't overwrite it later, we'll get + // an IOException. + // + // NOTE: FindBugs complains we are not checking return value here. + // Guess what? We don't care!!! + serializedFile.delete(); + + + cipherSpec = new CipherSpec( "AES/CBC/NoPadding", 128, 8, myIV); + FileOutputStream fos = new FileOutputStream(filename); + ObjectOutputStream out = new ObjectOutputStream(fos); + out.writeObject(cipherSpec); + out.close(); + fos.close(); + + FileInputStream fis = new FileInputStream(filename); + ObjectInputStream in = new ObjectInputStream(fis); + CipherSpec restoredCipherSpec = (CipherSpec)in.readObject(); + in.close(); + fis.close(); + + // check that cipherSpec and restoredCipherSpec are equal. Just + // compare them via their string representations. + assertEquals("Serialized restored CipherSpec differs from saved CipherSpec", + cipherSpec.toString(), restoredCipherSpec.toString() ); + + success = true; + } catch(IOException ex) { + ex.printStackTrace(System.err); + fail("testSerialization(): Unexpected IOException: " + ex); + } catch(ClassNotFoundException ex) { + ex.printStackTrace(System.err); + fail("testSerialization(): Unexpected ClassNotFoundException: " + ex); + } finally { + // If test succeeds, remove the file. If it fails, leave it behind + // for further analysis. + if ( success && serializedFile.exists() ) { + boolean deleted = serializedFile.delete(); + if ( !deleted ) { + try { + System.err.println("Unable to delete file: " + serializedFile.getCanonicalPath() ); + } catch (IOException e) { + ; // Ignore + } + } + } + } + } + + /** + * Run all the test cases in this suite. + * This is to allow running from {@code org.owasp.esapi.AllTests}. + */ + public static junit.framework.Test suite() { + TestSuite suite = new TestSuite(CipherSpecTest.class); + + return suite; + } +} diff --git a/src/test/java/org/owasp/esapi/crypto/CipherTextSerializerTest.java b/src/test/java/org/owasp/esapi/crypto/CipherTextSerializerTest.java new file mode 100644 index 000000000..fcf5be73e --- /dev/null +++ b/src/test/java/org/owasp/esapi/crypto/CipherTextSerializerTest.java @@ -0,0 +1,83 @@ +package org.owasp.esapi.crypto; + +import static org.junit.Assert.*; + +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.spec.IvParameterSpec; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.errors.EncryptionException; + +public class CipherTextSerializerTest { + private Cipher encryptor = null; + private IvParameterSpec ivSpec = null; // Note: FindBugs reports false positive + // about this being unread field. See + // testAsSerializedByteArray(). + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + } + + @AfterClass + public static void tearDownAfterClass() throws Exception { + } + + @Before + public void setUp() throws Exception { + encryptor = Cipher.getInstance("AES/CBC/PKCS5Padding"); + byte[] ivBytes = null; + ivBytes = ESAPI.randomizer().getRandomBytes(encryptor.getBlockSize()); + ivSpec = new IvParameterSpec(ivBytes); + } + + @After + public void tearDown() throws Exception { + System.out.flush(); + } + + @Test + public final void testAsSerializedByteArray() { + System.out.println("CipherTextSerializerTest.testAsSerializedByteArray() ..."); + CipherSpec cipherSpec = new CipherSpec(encryptor, 128); + cipherSpec.setIV(ivSpec.getIV()); + SecretKey key; + try { + key = CryptoHelper.generateSecretKey(cipherSpec.getCipherAlgorithm(), 128); + encryptor.init(Cipher.ENCRYPT_MODE, key, ivSpec); + + byte[] raw = encryptor.doFinal("Hello".getBytes("UTF8")); + CipherText ct = ESAPI.encryptor().encrypt(key, new PlainText("Hello") ); + assertTrue( ct != null ); // Here to eliminate false positive from FindBugs. + CipherTextSerializer cts = new CipherTextSerializer( ct ); + byte[] serializedBytes = cts.asSerializedByteArray(); + CipherText result = CipherText.fromPortableSerializedBytes(serializedBytes); + PlainText pt = ESAPI.encryptor().decrypt(key, result); + assertTrue( "Hello".equals( pt.toString() ) ); + } catch (Exception e) { + fail("Test failed: Caught exception: " + e.getClass().getName() + "; msg was: " + e); + e.printStackTrace(System.err); + } + } + + @Test + public final void testAsCipherText() { + try { + System.out.println("CipherTextSerializerTest.testAsCipherText() ..."); + CipherText ct = ESAPI.encryptor().encrypt( new PlainText("Hello") ); + CipherTextSerializer cts = new CipherTextSerializer( ct ); + CipherText result = cts.asCipherText(); + assertTrue( ct.equals(result) ); + PlainText pt = ESAPI.encryptor().decrypt(result); + assertTrue( "Hello".equals( pt.toString() ) ); + } catch (EncryptionException e) { + fail("Caught EncryptionException; exception msg: " + e); + } + } + +} diff --git a/src/test/java/org/owasp/esapi/crypto/CipherTextTest.java b/src/test/java/org/owasp/esapi/crypto/CipherTextTest.java new file mode 100644 index 000000000..5e8b036a1 --- /dev/null +++ b/src/test/java/org/owasp/esapi/crypto/CipherTextTest.java @@ -0,0 +1,341 @@ +package org.owasp.esapi.crypto; + +import static org.junit.Assert.*; + +import java.io.*; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.SecretKey; +import javax.crypto.spec.IvParameterSpec; + +import org.junit.*; +import org.junit.rules.TemporaryFolder; +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.errors.EncryptionException; +import org.owasp.esapi.reference.crypto.CryptoPolicy; + +import junit.framework.Assert; +import junit.framework.JUnit4TestAdapter; + +public class CipherTextTest { + + private CipherSpec cipherSpec_ = null; + private Cipher encryptor = null; + private Cipher decryptor = null; + private IvParameterSpec ivSpec = null; + @Rule + public TemporaryFolder tempFolder = new TemporaryFolder(); + + + @Before + public void setUp() throws Exception { + encryptor = Cipher.getInstance("AES/CBC/PKCS5Padding"); + decryptor = Cipher.getInstance("AES/CBC/PKCS5Padding"); + byte[] ivBytes = null; + ivBytes = ESAPI.randomizer().getRandomBytes(encryptor.getBlockSize()); + ivSpec = new IvParameterSpec(ivBytes); + } + + /** Test the default CTOR */ + @Test + public final void testCipherText() { + CipherText ct = new CipherText(); + + cipherSpec_ = new CipherSpec(); + assertTrue( ct.getCipherTransformation().equals( cipherSpec_.getCipherTransformation())); + assertTrue( ct.getBlockSize() == cipherSpec_.getBlockSize() ); + } + + @Test + public final void testCipherTextCipherSpec() { + cipherSpec_ = new CipherSpec("DESede/OFB8/NoPadding", 112); + CipherText ct = new CipherText( cipherSpec_ ); + assertTrue( ct.getRawCipherText() == null ); + assertTrue( ct.getCipherAlgorithm().equals("DESede") ); + assertTrue( ct.getKeySize() == cipherSpec_.getKeySize() ); + } + + @Test + public final void testCipherTextCipherSpecByteArray() + { + try { + CipherSpec cipherSpec = new CipherSpec(encryptor, 128); + cipherSpec.setIV(ivSpec.getIV()); + SecretKey key = + CryptoHelper.generateSecretKey(cipherSpec.getCipherAlgorithm(), 128); + encryptor.init(Cipher.ENCRYPT_MODE, key, ivSpec); + byte[] raw = encryptor.doFinal("Hello".getBytes("UTF8")); + CipherText ct = new CipherText(cipherSpec, raw); + assertTrue( ct != null ); + byte[] ctRaw = ct.getRawCipherText(); + assertTrue( ctRaw != null ); + assertArrayEquals(raw, ctRaw); + assertTrue( ct.getCipherTransformation().equals(cipherSpec.getCipherTransformation()) );; + assertTrue( ct.getCipherAlgorithm().equals(cipherSpec.getCipherAlgorithm()) ); + assertTrue( ct.getPaddingScheme().equals(cipherSpec.getPaddingScheme()) ); + assertTrue( ct.getBlockSize() == cipherSpec.getBlockSize() ); + assertTrue( ct.getKeySize() == cipherSpec.getKeySize() ); + byte[] ctIV = ct.getIV(); + byte[] csIV = cipherSpec.getIV(); + assertArrayEquals(ctIV, csIV); + } catch( Exception ex) { + // As far as test coverage goes, we really don't want this to be covered. + fail("Caught unexpected exception: " + ex.getClass().getName() + + "; exception message was: " + ex.getMessage()); + } + } + + + @Test + public final void testDecryptionUsingCipherText() { + try { + CipherSpec cipherSpec = new CipherSpec(encryptor, 128); + cipherSpec.setIV(ivSpec.getIV()); + assertTrue( cipherSpec.getIV() != null ); + assertTrue( cipherSpec.getIV().length > 0 ); + SecretKey key = + CryptoHelper.generateSecretKey(cipherSpec.getCipherAlgorithm(), 128); + encryptor.init(Cipher.ENCRYPT_MODE, key, ivSpec); + byte[] ctraw = encryptor.doFinal("Hello".getBytes("UTF8")); + CipherText ct = new CipherText(cipherSpec, ctraw); + assertTrue( ct.getCipherMode().equals("CBC") ); + assertTrue( ct.requiresIV() ); // CBC mode requires an IV. + String b64ctraw = ct.getBase64EncodedRawCipherText(); + assertTrue( b64ctraw != null); + assertArrayEquals( ESAPI.encoder().decodeFromBase64(b64ctraw), ctraw ); + decryptor.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(ct.getIV())); + byte[] ptraw = decryptor.doFinal(ESAPI.encoder().decodeFromBase64(b64ctraw)); + assertTrue( ptraw != null ); + assertTrue( ptraw.length > 0 ); + String plaintext = new String( ptraw, "UTF-8"); + assertTrue( plaintext.equals("Hello") ); + assertArrayEquals( ct.getRawCipherText(), ctraw ); + + byte[] ivAndRaw = ESAPI.encoder().decodeFromBase64( ct.getEncodedIVCipherText() ); + assertTrue( ivAndRaw.length > ctraw.length ); + assertTrue( ct.getBlockSize() == ( ivAndRaw.length - ctraw.length ) ); + } catch( Exception ex) { + // Note: FindBugs reports a false positive here... + // REC_CATCH_EXCEPTION: Exception is caught when Exception is not thrown + // but exceptions really can be thrown. This probably is because FindBugs + // examines the byte-code rather than the source code. However "fixing" this + // so that it doesn't complain will make the test much more complicated as there + // are about 3 or 4 different exception types. + // + // On a completely different note, as far as test coverage metrics goes, + // we really don't care if this is covered or nit as it is not our intent + // to be causing exceptions here. + ex.printStackTrace(System.err); + fail("Caught unexpected exception: " + ex.getClass().getName() + + "; exception message was: " + ex.getMessage()); + } + } + + @Test + public final void testMIC() { + try { + CipherSpec cipherSpec = new CipherSpec(encryptor, 128); + cipherSpec.setIV(ivSpec.getIV()); + SecretKey key = + CryptoHelper.generateSecretKey(cipherSpec.getCipherAlgorithm(), 128); + encryptor.init(Cipher.ENCRYPT_MODE, key, ivSpec); + byte[] ctraw = encryptor.doFinal("Hello".getBytes("UTF8")); + CipherText ct = new CipherText(cipherSpec, ctraw); + assertTrue( ct.getIV() != null && ct.getIV().length > 0 ); + SecretKey authKey = CryptoHelper.computeDerivedKey(key, key.getEncoded().length * 8, "authenticity"); + ct.computeAndStoreMAC( authKey ); + try { + ct.setIVandCiphertext(ivSpec.getIV(), ctraw); // Expected to log & throw. + } catch( Exception ex ) { + assertTrue( ex instanceof EncryptionException ); + } + try { + ct.setCiphertext(ctraw); // Expected to log and throw message about + // not being able to store raw ciphertext. + } catch( Exception ex ) { + assertTrue( ex instanceof EncryptionException ); + } + decryptor.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec( ct.getIV() ) ); + byte[] ptraw = decryptor.doFinal( ct.getRawCipherText() ); + assertTrue( ptraw != null && ptraw.length > 0 ); + ct.validateMAC( authKey ); + } catch( Exception ex) { + // As far as test coverage goes, we really don't want this to be covered. + ex.printStackTrace(System.err); + fail("Caught unexpected exception: " + ex.getClass().getName() + + "; exception message was: " + ex.getMessage()); + } + } + + /** Test portable serialization. */ + @Test public final void testPortableSerialization() throws Exception{ + System.out.println("CipherTextTest.testPortableSerialization()starting..."); + String filename = "ciphertext-portable.ser"; + File serializedFile = tempFolder.newFile(filename); + + + int keySize = 128; + if ( CryptoPolicy.isUnlimitedStrengthCryptoAvailable() ) { + keySize = 256; + } + CipherSpec cipherSpec = new CipherSpec(encryptor, keySize); + cipherSpec.setIV(ivSpec.getIV()); + SecretKey key; + try { + key = CryptoHelper.generateSecretKey(cipherSpec.getCipherAlgorithm(), keySize); + + encryptor.init(Cipher.ENCRYPT_MODE, key, ivSpec); + byte[] raw = encryptor.doFinal("This is my secret message!!!".getBytes("UTF8")); + CipherText ciphertext = new CipherText(cipherSpec, raw); + KeyDerivationFunction kdf = new KeyDerivationFunction( KeyDerivationFunction.PRF_ALGORITHMS.HmacSHA1 ); + SecretKey authKey = kdf.computeDerivedKey(key, key.getEncoded().length * 8, "authenticity"); + ciphertext.computeAndStoreMAC( authKey ); +// System.err.println("Original ciphertext being serialized: " + ciphertext); + byte[] serializedBytes = ciphertext.asPortableSerializedByteArray(); + + FileOutputStream fos = new FileOutputStream(serializedFile); + fos.write(serializedBytes); + // Note: FindBugs complains that this test may fail to close + // the fos output stream. We don't really care. + fos.close(); + + // NOTE: FindBugs complains about this (OS_OPEN_STREAM). It apparently + // is too lame to know that 'fis.read()' is a serious side-effect. + FileInputStream fis = new FileInputStream(serializedFile); + int avail = fis.available(); + byte[] bytes = new byte[avail]; + fis.read(bytes, 0, avail); + + // Sleep one second to prove that the timestamp on the original + // CipherText object is the one that we use and not just the + // current time. Only after that, do we restore the serialized bytes. + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + ; // Ignore + } + CipherText restoredCipherText = CipherText.fromPortableSerializedBytes(bytes); +// System.err.println("Restored ciphertext: " + restoredCipherText); + assertTrue( ciphertext.equals(restoredCipherText)); + } catch (EncryptionException e) { + Assert.fail("Caught EncryptionException: " + e); + } catch (FileNotFoundException e) { + Assert.fail("Caught FileNotFoundException: " + e); + } catch (IOException e) { + Assert.fail("Caught IOException: " + e); + } catch (Exception e) { + Assert.fail("Caught Exception: " + e); + } finally { + // FindBugs complains that we are ignoring this return value. We really don't care. + serializedFile.delete(); + } + } + + /** Test portable serialization for backward compatibility with ESAPI 2.0. */ + @Test public final void testPortableSerializationBackwardCompatibility() { + System.out.println("testPortableSerializationBackwardCompatibility()starting..."); + String filename = "src/test/resources/ESAPI2.0-ciphertext-portable.ser"; // Do NOT remove + File serializedFile = new File(filename); + + try { + // String expectedMsg = "This is my secret message!!!"; + + // NOTE: FindBugs complains about this (OS_OPEN_STREAM). It apparently + // is too lame to know that 'fis.read()' is a serious side-effect. + FileInputStream fis = new FileInputStream(serializedFile); + int avail = fis.available(); + byte[] bytes = new byte[avail]; + fis.read(bytes, 0, avail); + // We can't go as far and decrypt it because the file was encrypted using a + // temporary session key. + CipherText restoredCipherText = CipherText.fromPortableSerializedBytes(bytes); + assertTrue( restoredCipherText != null ); + int retrievedKdfVersion = restoredCipherText.getKDFVersion(); + } catch (EncryptionException e) { + Assert.fail("Caught EncryptionException: " + e); + } catch (FileNotFoundException e) { + Assert.fail("Caught FileNotFoundException: " + e); + } catch (IOException e) { + Assert.fail("Caught IOException: " + e); + } catch (Exception e) { + Assert.fail("Caught Exception: " + e); + } finally { + ; // Do NOT delete the file. + } + } + + /** Test Java serialization. */ + @Test public final void testJavaSerialization() { + String filename = "ciphertext.ser"; + + try { + File serializedFile = tempFolder.newFile(filename); + + CipherSpec cipherSpec = new CipherSpec(encryptor, 128); + cipherSpec.setIV(ivSpec.getIV()); + SecretKey key = + CryptoHelper.generateSecretKey(cipherSpec.getCipherAlgorithm(), 128); + encryptor.init(Cipher.ENCRYPT_MODE, key, ivSpec); + byte[] raw = encryptor.doFinal("This is my secret message!!!".getBytes("UTF8")); + CipherText ciphertext = new CipherText(cipherSpec, raw); + + FileOutputStream fos = new FileOutputStream(serializedFile); + ObjectOutputStream out = new ObjectOutputStream(fos); + out.writeObject(ciphertext); + out.close(); + fos.close(); + + FileInputStream fis = new FileInputStream(serializedFile); + ObjectInputStream in = new ObjectInputStream(fis); + CipherText restoredCipherText = (CipherText)in.readObject(); + in.close(); + fis.close(); + + // check that ciphertext and restoredCipherText are equal. Requires + // multiple checks. (Hmmm... maybe overriding equals() and hashCode() + // is in order???) + assertEquals("1: Serialized restored CipherText differs from saved CipherText", + ciphertext.toString(), restoredCipherText.toString()); + assertArrayEquals("2: Serialized restored CipherText differs from saved CipherText", + ciphertext.getIV(), restoredCipherText.getIV()); + assertEquals("3: Serialized restored CipherText differs from saved CipherText", + ciphertext.getBase64EncodedRawCipherText(), + restoredCipherText.getBase64EncodedRawCipherText()); + + } catch(IOException ex) { + ex.printStackTrace(System.err); + fail("testJavaSerialization(): Unexpected IOException: " + ex); + } catch(ClassNotFoundException ex) { + ex.printStackTrace(System.err); + fail("testJavaSerialization(): Unexpected ClassNotFoundException: " + ex); + } catch (EncryptionException ex) { + ex.printStackTrace(System.err); + fail("testJavaSerialization(): Unexpected EncryptionException: " + ex); + } catch (IllegalBlockSizeException ex) { + ex.printStackTrace(System.err); + fail("testJavaSerialization(): Unexpected IllegalBlockSizeException: " + ex); + } catch (BadPaddingException ex) { + ex.printStackTrace(System.err); + fail("testJavaSerialization(): Unexpected BadPaddingException: " + ex); + } catch (InvalidKeyException ex) { + ex.printStackTrace(System.err); + fail("testJavaSerialization(): Unexpected InvalidKeyException: " + ex); + } catch (InvalidAlgorithmParameterException ex) { + ex.printStackTrace(System.err); + fail("testJavaSerialization(): Unexpected InvalidAlgorithmParameterException: " + ex); + } + } + + /** + * Run all the test cases in this suite. + * This is to allow running from {@code org.owasp.esapi.AllTests} which + * uses a JUnit 3 test runner. + */ + public static junit.framework.Test suite() { + return new JUnit4TestAdapter(CipherTextTest.class); + } +} diff --git a/src/test/java/org/owasp/esapi/crypto/CryptoHelperTest.java b/src/test/java/org/owasp/esapi/crypto/CryptoHelperTest.java new file mode 100644 index 000000000..b315867f5 --- /dev/null +++ b/src/test/java/org/owasp/esapi/crypto/CryptoHelperTest.java @@ -0,0 +1,195 @@ +package org.owasp.esapi.crypto; + +import static org.junit.Assert.*; + +import java.util.Random; + +import org.junit.Test; + +import javax.crypto.SecretKey; + +import junit.framework.JUnit4TestAdapter; + +import org.owasp.esapi.crypto.CryptoHelper; +import org.owasp.esapi.errors.EncryptionException; + +public class CryptoHelperTest { + + @Test + public final void testGenerateSecretKeySunnyDay() { + try { + SecretKey key = CryptoHelper.generateSecretKey("AES", 128); + assertTrue(key.getAlgorithm().equals("AES")); + assertTrue(128 / 8 == key.getEncoded().length); + } catch (EncryptionException e) { + // OK if not covered in code coverage -- not expected. + fail("Caught unexpected EncryptionException; msg was " + + e.getMessage()); + } + } + + @Test(expected = EncryptionException.class) + public final void testGenerateSecretKeyEncryptionException() + throws EncryptionException { + SecretKey key = CryptoHelper.generateSecretKey("NoSuchAlg", 128); + assertTrue(key == null); // Not reached! + } + + @Test + public final void testOverwriteByteArrayByte() { + byte[] secret = "secret password".getBytes(); + int len = secret.length; + CryptoHelper.overwrite(secret, (byte) 'x'); + assertTrue(secret.length == len); // Length unchanged + assertTrue(checkByteArray(secret, (byte) 'x')); // Filled with 'x' + } + + @Test + public final void testCopyByteArraySunnyDay() { + byte[] src = new byte[20]; + fillByteArray(src, (byte) 'A'); + byte[] dest = new byte[20]; + fillByteArray(dest, (byte) 'B'); + CryptoHelper.copyByteArray(src, dest); + assertTrue(checkByteArray(src, (byte) 'A')); // Still filled with 'A' + assertTrue(checkByteArray(dest, (byte) 'A')); // Now filled with 'B' + } + + @Test(expected = NullPointerException.class) + public final void testCopyByteArraySrcNullPointerException() { + byte[] ba = new byte[16]; + CryptoHelper.copyByteArray(null, ba, ba.length); + } + + @Test(expected = NullPointerException.class) + public final void testCopyByteArrayDestNullPointerException() { + byte[] ba = new byte[16]; + CryptoHelper.copyByteArray(ba, null, ba.length); + } + + @Test(expected = IndexOutOfBoundsException.class) + public final void testCopyByteArrayIndexOutOfBoundsException() { + byte[] ba8 = new byte[8]; + byte[] ba16 = new byte[16]; + CryptoHelper.copyByteArray(ba8, ba16, ba16.length); + } + + @Test + public final void testArrayCompare() { + byte[] ba1 = new byte[32]; + byte[] ba2 = new byte[32]; + byte[] ba3 = new byte[48]; + + // Note: Don't need cryptographically secure random numbers for this! + Random prng = new Random(); + + prng.nextBytes(ba1); + prng.nextBytes(ba2); + prng.nextBytes(ba3); + + /* + * Unfortunately, can't rely no the nanosecond timer because as the + * Javadoc for System.nanoTime() states, " No guarantees are made + * about how frequently values change", so this is not very reliable. + * + * However, on can uncomment the code and observe that elapsed times + * are generally less than 10 millionth of a second. I suppose if we + * declared a large enough epsilon, we could make it work, but it is + * easier to convince yourself from the CryptoHelper.arrayCompare() code + * itself that it always goes through all the bits of the byte array + * if it compares any bits at all. + */ + +// long start, stop, diff; + +// start = System.nanoTime(); + assertTrue(CryptoHelper.arrayCompare(null, null)); +// stop = System.nanoTime(); +// diff = stop - start; +// System.out.println("diff: " + diff + " nanosec"); + +// start = System.nanoTime(); + assertTrue(CryptoHelper.arrayCompare(ba1, ba1)); +// stop = System.nanoTime(); +// diff = stop - start; +// System.out.println("diff: " + diff + " nanosec"); + +// start = System.nanoTime(); + assertFalse(CryptoHelper.arrayCompare(ba1, ba2)); +// stop = System.nanoTime(); +// diff = stop - start; +// System.out.println("diff: " + diff + " nanosec"); + +// start = System.nanoTime(); + assertFalse(CryptoHelper.arrayCompare(ba1, ba3)); +// stop = System.nanoTime(); +// diff = stop - start; +// System.out.println("diff: " + diff + " nanosec"); + +// start = System.nanoTime(); + assertFalse(CryptoHelper.arrayCompare(ba1, null)); +// stop = System.nanoTime(); +// diff = stop - start; +// System.out.println("diff: " + diff + " nanosec"); + +// start = System.nanoTime(); + assertFalse(CryptoHelper.arrayCompare(null, ba1)); +// stop = System.nanoTime(); +// diff = stop - start; +// System.out.println("diff: " + diff + " nanosec"); + + ba2 = ba1; +// start = System.nanoTime(); + assertTrue(CryptoHelper.arrayCompare(ba1, ba2)); +// stop = System.nanoTime(); +// diff = stop - start; +// System.out.println("diff: " + diff + " nanosec"); + } + + @Test + public final void testIsValidKDFVersion() { + assertTrue( CryptoHelper.isValidKDFVersion(20110203, false, false)); + assertTrue( CryptoHelper.isValidKDFVersion(20130830, false, false)); + assertTrue( CryptoHelper.isValidKDFVersion(33330303, false, false)); + assertTrue( CryptoHelper.isValidKDFVersion(99991231, false, false)); + + assertFalse( CryptoHelper.isValidKDFVersion(0, false, false)); + assertFalse( CryptoHelper.isValidKDFVersion(99991232, false, false)); + assertFalse( CryptoHelper.isValidKDFVersion(20110202, false, false)); + + assertTrue( CryptoHelper.isValidKDFVersion(20110203, true, false)); + assertTrue( CryptoHelper.isValidKDFVersion(KeyDerivationFunction.kdfVersion, true, false)); + assertFalse( CryptoHelper.isValidKDFVersion(KeyDerivationFunction.kdfVersion + 1, true, false)); + + try { + CryptoHelper.isValidKDFVersion(77777777, true, true); + fail("Failed to CryptoHelper.isValidKDFVersion() failed to throw IllegalArgumentException."); + } + catch (Exception e) { + assertTrue( e instanceof IllegalArgumentException); + } + } + + private void fillByteArray(byte[] ba, byte b) { + for (int i = 0; i < ba.length; i++) { + ba[i] = b; + } + } + + private boolean checkByteArray(byte[] ba, byte b) { + for (int i = 0; i < ba.length; i++) { + if (ba[i] != b) { + return false; + } + } + return true; + } + + /** + * Run all the test cases in this suite. This is to allow running from + * {@code org.owasp.esapi.AllTests} which uses a JUnit 3 test runner. + */ + public static junit.framework.Test suite() { + return new JUnit4TestAdapter(CryptoHelperTest.class); + } +} diff --git a/src/test/java/org/owasp/esapi/crypto/CryptoTokenTest.java b/src/test/java/org/owasp/esapi/crypto/CryptoTokenTest.java new file mode 100644 index 000000000..250cdd457 --- /dev/null +++ b/src/test/java/org/owasp/esapi/crypto/CryptoTokenTest.java @@ -0,0 +1,409 @@ +package org.owasp.esapi.crypto; + +import static org.junit.Assert.*; + +import java.util.Date; +import java.util.Map; + +import javax.crypto.SecretKey; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.owasp.esapi.errors.EncryptionException; +import org.owasp.esapi.errors.ValidationException; + +public class CryptoTokenTest { + + private SecretKey skey1 = null; + private SecretKey skey2 = null; + + @Before + public void setUp() throws Exception { + skey1 = CryptoHelper.generateSecretKey("AES", 128); + skey2 = CryptoHelper.generateSecretKey("AES", 128); + } + + @After + public void tearDown() throws Exception { + } + + @Test + public final void testCryptoToken() { + // Test with default CTOR + CryptoToken ctok = new CryptoToken(); + CTORtest( ctok, null ); + } + + @Test + public final void testCryptoTokenSecretKey() { + // Test with default CTOR + CryptoToken ctok = new CryptoToken(skey1); + CTORtest( ctok, skey1 ); + } + + private void CTORtest(CryptoToken ctok, SecretKey sk) { + String token = null; + try { + if ( sk == null ) { + token = ctok.getToken(); // Use default key, Encryptor.MasterKey + } else { + token = ctok.getToken(sk); + } + } catch (EncryptionException e) { + fail("Caught unexpected exception on getToken() call: " + e); + } + assertNotNull(token); + assertEquals( ctok.getUserAccountName(), CryptoToken.ANONYMOUS_USER); + assertFalse( ctok.isExpired() ); + long expTime1 = ctok.getExpiration(); + + CryptoToken ctok2 = null; + try { + if ( sk == null ) { + ctok2 = new CryptoToken( token ); // Use default key, Encryptor.MasterKey + } else { + ctok2 = new CryptoToken( sk, token ); + } + } catch (EncryptionException e) { + e.printStackTrace(System.err); + fail("Caught unexpected exception on CryptoToken CTOR: " + e); + } + long expTime2 = ctok2.getExpiration(); + assertTrue("Expected expiration for ctok2 (" + new Date(expTime2) + + ") to be later than of ctok (" + new Date(expTime1) + ").", + ( expTime2 >= expTime1 ) ); + } + + @Test + public final void testCryptoTokenSecretKeyString() { + CryptoToken ctok1 = new CryptoToken(skey1); + try { + ctok1.setUserAccountName("kevin.w.wall@gmail.com"); + } catch (ValidationException e) { + fail("Failed to set user account name because of ValidationException: " + e); + } + try { + ctok1.setAttribute("role-name", "admin"); + ctok1.setAttribute("company", "Qwest"); + } catch (ValidationException e) { + fail("Failed to set 'role-name' or 'company' attribute because of ValidationException: " + e); + } + String token1 = null; + String token2 = null; + boolean passedFirst = false; + try { + token1 = ctok1.getToken(); + passedFirst = true; + token2 = ctok1.getToken(skey2); + assertFalse("Tokens unexpectedly equal!", token1.equals(token2) ); + } catch (EncryptionException e) { + fail("Failed to retrieve " + (passedFirst ? "1st" : "2nd" ) + " encrypted token"); + } + CryptoToken ctok2 = null; + try { + ctok2 = new CryptoToken(skey1, token1); + token2 = ctok2.getToken(); + ctok2.setAttribute("company", "CenturyLink"); + } catch (EncryptionException e) { + fail("Failed to decrypt token1 or re-encrypt token; exception: " + e); + } catch (ValidationException e) { + fail("Failed with ValidationException on resetting 'company' attribute: " + e); + } + String userName = ctok2.getUserAccountName(); + String roleAttr = ctok2.getAttribute("role-name"); + String company = ctok2.getAttribute("company"); + assertEquals( userName, "kevin.w.wall@gmail.com"); + assertEquals( roleAttr, "admin"); + assertEquals( company, "CenturyLink"); + } + + @Test + public final void testExpiration() { + CryptoToken ctok = new CryptoToken(); + ctok.setExpiration(2); // 2 seconds + CryptoToken ctok2 = null; + try { + ctok2 = new CryptoToken( ctok.getToken() ); + } catch (EncryptionException e1) { + fail("Failed to decrypt token"); + } + assertFalse( ctok.isExpired() ); + assertFalse( ctok2.isExpired() ); + nap(2); + + assertTrue( ctok.isExpired() ); + assertTrue( ctok2.isExpired() ); + + try { + ctok2.updateToken(2); + } catch (EncryptionException e) { + fail("EncryptionException for token ctok2 by adding additional 2 sec; exception: " + e); + } catch (ValidationException e) { + // This would be caused if the token would already be expired even AFTER adding + // an additional 2 seconds. We don't expect this, but it could happen if the OS + // causes this process to stall for a bit while running higher priority processes. + // We don't expect this here though. (Have a test for that below.) + fail("Failed to update token ctok2 by adding additional 2 sec; exception: " + e); + } + assertFalse( ctok2.isExpired() ); + nap(3); + try { + ctok2.updateToken(1); + fail("Expected ValidationException!"); + } catch (EncryptionException e) { + fail("EncryptionException for token ctok2 by adding additional 2 sec; exception: " + e); + } catch (ValidationException e) { + // Probably a bad idea to test this in the following manner as + // message could change whenever. + // assertEquals( e.getMessage(), "Token timed out."); + ; // Ignore -- in this case, we expect it! + } + } + + @Test + public final void testSetUserAccountName() { + CryptoToken ctok = new CryptoToken(); + try { + ctok.setUserAccountName("kevin.w.wall@gmail.com"); + ctok.setUserAccountName("kevin"); + ctok.setUserAccountName("name-with-hyphen"); + ctok.setUserAccountName("x"); + ctok.setUserAccountName("X"); + } catch (ValidationException e) { + fail("Failed to set user account name because of ValidationException: " + e); + } + try { + ctok.setUserAccountName(""); // Can't be empty + fail("Failed to throw expected ValidationException"); + } catch (ValidationException e) { + ; // Success + } + try { + ctok.setUserAccountName(null); // Can't be null + // Should get one of these, depending on whether or not assertions are enabled. + fail("Failed to throw expected IllegalArgumentException"); + } catch (IllegalArgumentException e) { + ; // Success + } catch (Exception e) { + fail("Wrong type of exception thrown: " + e); + } + try { + ctok.setUserAccountName("1773g4l"); // Can't start w/ numeric + fail("Failed to throw expected ValidationException"); + } catch (ValidationException e) { + ; // Success + } + try { + ctok.setUserAccountName("invalid/char"); // '/' is not valid. + fail("Failed to throw expected ValidationException"); + } catch (ValidationException e) { + ; // Success + } + + } + + @Test + public final void testSetExpirationDate() { + CryptoToken ctok = new CryptoToken(); + try { + ctok.setExpiration(null); + fail("Expected IllegalArgumentException on ctok.setExpiration(null)."); + } catch (IllegalArgumentException e) { + ; // Success + } catch (Exception e) { + fail("Caught unexpected exception: " + e); + } + + try { + Date now = new Date(); + nap(1); + ctok.setExpiration(now); + fail("Expected IllegalArgumentException on ctok.setExpiration(Date) w/ Date in past."); + } catch (IllegalArgumentException e) { + ; // Success + } catch (Exception e) { + fail("Caught unexpected exception: " + e); + } + + try { + ctok.setExpiration(-1); + fail("Expected IllegalArgumentException on ctok.setExpiration(int) w/ negative interval."); + } catch (IllegalArgumentException e) { + ; // Success + } catch (Exception e) { + fail("Caught unexpected exception: " + e); + } + + try { + Date maxDate = new Date( Long.MAX_VALUE - 1 ); + ctok.setExpiration( maxDate ); + ctok.updateToken(1); + fail("Expected ArithmeticException on ctok.setExpiration(int)."); + } catch (ArithmeticException e) { + ; // Success + } catch (Exception e) { + fail("Caught unexpected exception: " + e); + } + } + + + @Test + public final void testSetAndGetAttribute() { + CryptoToken ctok = new CryptoToken(); + + // Test case where attr name is empty string. Expect ValidationException + try { + ctok.setAttribute("", "someValue"); + fail("Expected ValidationException on ctok.setAttribute()."); + } catch (ValidationException e) { + ; // Success + } catch (Exception e) { + fail("Caught unexpected exception: " + e); + } + + // Test case where attr name does not match regex "[A-Za-z0-9_.-]+". + // Expect ValidationException. + try { + ctok.setAttribute("/my/attr/", "someValue"); + fail("Expected ValidationException on ctok.setAttribute() w/ invalid name."); + } catch (ValidationException e) { + ; // Success + } catch (Exception e) { + fail("Caught unexpected exception: " + e); + } + + // Test case where attr VALUE is not. Expect ValidationException. + try { + ctok.setAttribute("myAttr", null); + fail("Expected ValidationException on ctok.setAttribute() w/ null value."); + } catch (ValidationException e) { + ; // Success + } catch (Exception e) { + fail("Caught unexpected exception: " + e); + } + + // Test cases that should work. Specifically we want to test cases + // where attribute values contains each of the values that will + // be quoted, namely: '\', '=', and ';' + try { + String[] attrValues = { "\\", ";", "=", "foo=", "bar\\=", "foobar=\"" }; + String complexValue = "kwwall;1291183520293;abc=x=yx;xyz=;efg=a;a;;bbb=quotes\\tuff"; + + ctok.setAttribute("complexAttr", complexValue); + ctok.setAttribute("..--__", ""); // Ugly weird but legal attr name; empty is legal value. + + for ( int i = 0; i < attrValues.length; i++ ) { + String attrName = "attr" + i; + String attrVal = attrValues[i]; + + ctok.setAttribute( attrName, attrVal ); + } + + String tokenVal = ctok.getToken(); + assertNotNull("tokenVal should not be null", tokenVal); + + CryptoToken ctok2 = new CryptoToken(tokenVal); + + String weirdAttr = ctok2.getAttribute("..--__"); + assertTrue("Expecting empty string for value of weird attr, but got: " + weirdAttr, + weirdAttr.equals("")); + + String complexAttr = ctok2.getAttribute("complexAttr"); + assertNotNull(complexAttr); + assertTrue("complexAttr has unexpected value of " + complexAttr, complexAttr.equals(complexValue) ); + + for ( int i = 0; i < attrValues.length; i++ ) { + String attrName = "attr" + i; + String attrVal = attrValues[i]; + String retrieved = ctok2.getAttribute( attrName ); + String assertMsg = "Exptected attribute '" + attrName + "' to have value of '" + attrVal + "', but had value of '" + retrieved; + + assertTrue( assertMsg, attrVal.equals( attrVal ) ); + ctok.setAttribute( attrName, attrVal ); + } + + } catch (ValidationException e) { + fail("Caught unexpected ValidationException: " + e); + } catch (Exception e) { + e.printStackTrace(System.err); + fail("Caught unexpected exception: " + e); + } + } + + // Test the following two methods in CryptoToken: + // public void addAttributes(final Map attrs) throws ValidationException + // public Map getAttributes() + @Test + public final void testAddandGetAttributes() { + CryptoToken ctok = new CryptoToken(); + Map origAttrs = null; + + try { + ctok.setAttribute("attr1", "value1"); + ctok.setAttribute("attr2", "value2"); + origAttrs = ctok.getAttributes(); + origAttrs.put("attr2", "NewValue2"); + String val = ctok.getAttribute("attr2"); + assertTrue("Attribute map not cloned; crypto token attr changed!", + val.equals("value2") ); // Confirm original attr2 did not change + + origAttrs.put("attr3", "value3"); + origAttrs.put("attr4", "value4"); + ctok.addAttributes(origAttrs); + } catch (ValidationException e) { + fail("Caught unexpected ValidationException: " + e); + } + try { + String token = ctok.getToken(); + ctok = new CryptoToken(token); + } catch (EncryptionException e) { + fail("Caught unexpected EncryptionException: " + e); + } + + Map extractedAttrs = ctok.getAttributes(); + assertTrue("Expected extracted attrs to be equal to original attrs", + origAttrs.equals(extractedAttrs)); + + origAttrs.put("/illegalAttrName/", "someValue"); + try { + ctok.addAttributes(origAttrs); + fail("Expected ValidationException"); + } catch (ValidationException e) { + ; // Success + } catch (Exception e) { + e.printStackTrace(System.err); + fail("Caught unexpected exception: " + e); + } + + origAttrs.clear(); + CryptoToken ctok2 = null; + try { + ctok.clearAttributes(); // Clear any attributes + ctok2 = new CryptoToken( ctok.getToken() ); + } catch (EncryptionException e) { + fail("Unexpected EncryptionException"); + } + + try { + ctok2.addAttributes(origAttrs); // Add (empty) attribute map + } catch (ValidationException e) { + fail("Unexpected ValidationException"); + } + extractedAttrs = ctok2.getAttributes(); + assertTrue("Expected extracted attributes to be empty", extractedAttrs.isEmpty() ); + } + + // Sleep n seconds. + private static void nap(int n) { + try { + System.out.println("Sleeping " + n + " seconds..."); + // adds additional time to make sure we sleep more than n seconds + int additionalTimeToSleep = 100; + Thread.sleep( n * 1000 + additionalTimeToSleep ); + } catch (InterruptedException e) { + ; // Ignore + } + } +} diff --git a/src/test/java/org/owasp/esapi/crypto/ESAPICryptoMACByPassTest.java b/src/test/java/org/owasp/esapi/crypto/ESAPICryptoMACByPassTest.java new file mode 100644 index 000000000..a93ce6cfb --- /dev/null +++ b/src/test/java/org/owasp/esapi/crypto/ESAPICryptoMACByPassTest.java @@ -0,0 +1,232 @@ +/* + * OWASP Enterprise Security API (ESAPI) - Google issue # 306. + * (i.e., GitHub issue 312). + * + * 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) 2013 - The OWASP Foundation + * ESAPI is published by OWASP under the new BSD license. You should read + * and accept the LICENSE before you use, modify, and/or redistribute this + * software. + * + * Full credit for this JUnit to illustrate what is now Google Issue # 306 + * goes to Philippe Arteau . Originally + * published 2013/08/21 to ESAPI-DEV mailing list. Shows that both + * ESAPI 2.0 and 2.0.1 is vulnerable. Minor tweaks by Kevin W. Wall. + * + * Original class name: SignatureByPassTest. + * + * NOTE: If this test fails, your version of ESAPI is vulnerable (or you have + * it configured not to require a MAC which you should NOT do). + */ + +package org.owasp.esapi.crypto; + +import org.apache.commons.codec.binary.Hex; +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.crypto.CipherText; +import org.owasp.esapi.crypto.PlainText; +import org.owasp.esapi.errors.EncryptionException; +import org.owasp.esapi.util.ByteConversionUtil; + +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; +import java.io.ByteArrayOutputStream; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Field; +import java.security.NoSuchAlgorithmException; +import java.security.spec.InvalidKeySpecException; +import java.util.Date; + +import static org.junit.Assert.*; +import org.junit.Before; +import org.junit.Test; + + +public class ESAPICryptoMACByPassTest { + + @Before + public void setUp() throws NoSuchAlgorithmException, InvalidKeySpecException { + ; // Do any prerequisite setup here. + } + + @Test + public void testMacBypass() throws EncryptionException, NoSuchFieldException, IllegalAccessException { + + byte[] bkey = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0xA,0x0B,0x0C,0x0D,0x0E,0x0F}; //Truly random key. ;-) + SecretKey sk = new SecretKeySpec(bkey,"AES"); + + //Encryption with MAC + String originalMessage = "Cryptography!?!?"; + System.out.printf("Encrypting the message '%s'\n", originalMessage); + // Until there is a better way to do this. But this is much easier + // than having to set up a custom ESAPI.properties file just for + // this test. + // + // NOTE: Philippe Arteau's original exploit used "AES/OFB/NoPadding" + // so that one could see that the effect of the decryption would + // be "Craptography!?!?". However, if you wish to do that, then + // you must also change the ESAPI.properties file used by ESAPI + // JUnit tests sp that "OFB" is accepted as an allowed cipher + // mode. The easiest way to do that (if you are still not convinced) + // is to add "OFB" mode to Encryptor.cipher_modes.additional_allowed; + // e.g., Encryptor.cipher_modes.additional_allowed=CBC,OFB + // + String origCipherXform = + ESAPI.securityConfiguration().setCipherTransformation("AES/CBC/NoPadding"); + CipherText ct = ESAPI.encryptor().encrypt(sk,new PlainText(originalMessage)); + + //Serialize the ciphertext in order to send it over the wire.. + byte[] serializedCt = ct.asPortableSerializedByteArray(); + + //Malicious modification + byte[] modifiedCt = tamperCipherText(serializedCt); + + //Decrypt + CipherText modifierCtObj = CipherText.fromPortableSerializedBytes(modifiedCt); + try { + ESAPI.securityConfiguration().setCipherTransformation(origCipherXform); + // This decryption should fail by throwing an EncryptionException + // if ESAPI crypto is NOT vulnerable and you never get to the + // subsequent lines in the try block. + PlainText pt = ESAPI.encryptor().decrypt(sk,modifierCtObj); + System.out.printf("Decrypting to '%s' (probably will look like garbage!)\n", new String(pt.asBytes())); + System.out.println("This ESAPI version vulnerable to MAC by-pass described in GitHub issue # 312! Upgrade to latest version."); + fail("This ESAPI version is vulnerable to MAC by-pass described in GitHub issue # 312! Upgrade to latest version."); + } catch(EncryptionException eex) { + String errMsg = eex.getMessage(); + // See private String DECRYPTION_FAILED in JavaEncryptor. + String expectedError = "Decryption failed; see logs for details."; + assertTrue( errMsg.equals(expectedError) ); + System.out.println("testMacByPass(): Attempted decryption after MAC tampering failed."); + System.out.println("Fix of issue # 306 successful. Crypto MAC by-pass test failed; exception was: [" + eex + "]"); + } + } + + /** + * The modification of the ciphertext is done in a separate method to show that only the generate CipherText object is use. + * @param serializeCt + */ + private byte[] tamperCipherText(byte[] serializeCt) throws EncryptionException, NoSuchFieldException, IllegalAccessException { + CipherText ct = CipherText.fromPortableSerializedBytes(serializeCt); + + //Ciphertext metadata + //System.out.println(ct.toString()); + + byte[] cipherTextMod = ct.getRawCipherText(); + + System.out.printf("Original ciphertext\t'%s'\n",String.valueOf(Hex.encodeHex(cipherTextMod))); + + cipherTextMod[2] ^= 'y' ^ 'a'; //Alter the 3rd character + + System.out.printf("Modify ciphertext\t'%s'\n",String.valueOf(Hex.encodeHex(cipherTextMod))); + + //MAC ... what MAC ? + Field f2 = ct.getClass().getDeclaredField("separate_mac_"); + f2.setAccessible(true); + f2.set(ct,null); //mac byte array set to null + + //Changing CT + Field f3 = ct.getClass().getDeclaredField("raw_ciphertext_"); + f3.setAccessible(true); + f3.set(ct,cipherTextMod); + + //return ct.asPortableSerializedByteArray(); //Will complain about missing mac + //return new CipherTextSerializer(ct).asSerializedByteArray(); //NPE on mac.length + return serialize(ct); //Modify version of CipherTextSerializer.asSerializedByteArray() + } + + ///////////////////////////////////////////////////////////////////// + // The following code is a modified version of CipherTextSerializer + ///////////////////////////////////////////////////////////////////// + + private byte[] serialize(CipherText cipherText_) { + int kdfInfo = cipherText_.getKDFInfo(); + + long timestamp = cipherText_.getEncryptionTimestamp(); + String cipherXform = cipherText_.getCipherTransformation(); + + short keySize = (short) cipherText_.getKeySize(); + + short blockSize = (short)cipherText_.getBlockSize(); + byte[] iv = cipherText_.getIV(); + + short ivLen = (short)iv.length; + byte[] rawCiphertext = cipherText_.getRawCipherText(); + int ciphertextLen = rawCiphertext.length; + + byte[] mac = cipherText_.getSeparateMAC(); + + short macLen = 0;//(short)mac.length; //<-------------- The only modification to the serialization + + return computeSerialization(kdfInfo, timestamp, cipherXform, keySize, blockSize, ivLen, iv, ciphertextLen, rawCiphertext, macLen, mac); + } + + private byte[] computeSerialization(int kdfInfo, long timestamp, String cipherXform, short keySize, short blockSize, short ivLen, byte[] iv, int ciphertextLen, byte[] rawCiphertext, short macLen, byte[] mac) + { + debug("computeSerialization: kdfInfo = " + kdfInfo); + debug("computeSerialization: timestamp = " + new Date(timestamp)); + debug("computeSerialization: cipherXform = " + cipherXform); + debug("computeSerialization: keySize = " + keySize); + debug("computeSerialization: blockSize = " + blockSize); + debug("computeSerialization: ivLen = " + ivLen); + debug("computeSerialization: ciphertextLen = " + ciphertextLen); + debug("computeSerialization: macLen = " + macLen); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + writeInt(baos, kdfInfo); + writeLong(baos, timestamp); + String[] parts = cipherXform.split("/"); + assert (parts.length == 3) : "Malformed cipher transformation"; + writeString(baos, cipherXform); + writeShort(baos, keySize); + writeShort(baos, blockSize); + writeShort(baos, ivLen); + if (ivLen > 0) baos.write(iv, 0, iv.length); + writeInt(baos, ciphertextLen); + baos.write(rawCiphertext, 0, rawCiphertext.length); + writeShort(baos, macLen); + if (macLen > 0) baos.write(mac, 0, mac.length); + return baos.toByteArray(); + } + + private static void debug(String msg) { + // System.err.println(msg); + } + + private void writeShort(ByteArrayOutputStream baos, short s) { + byte[] shortAsByteArray = ByteConversionUtil.fromShort(s); + assert (shortAsByteArray.length == 2); + baos.write(shortAsByteArray, 0, 2); + } + + private void writeInt(ByteArrayOutputStream baos, int i) { + byte[] intAsByteArray = ByteConversionUtil.fromInt(i); + baos.write(intAsByteArray, 0, 4); + } + + private void writeLong(ByteArrayOutputStream baos, long l) { + byte[] longAsByteArray = ByteConversionUtil.fromLong(l); + assert (longAsByteArray.length == 8); + baos.write(longAsByteArray, 0, 8); + } + + private void writeString(ByteArrayOutputStream baos, String str) + { + try + { + assert ((str != null) && (str.length() > 0)); + byte[] bytes = str.getBytes("UTF8"); + assert (bytes.length < 32767) : "writeString: String exceeds max length"; + writeShort(baos, (short)bytes.length); + baos.write(bytes, 0, bytes.length); + } + catch (UnsupportedEncodingException e) + { + System.err.println("writeString: " + e.getMessage()); + } + } + +} diff --git a/src/test/java/org/owasp/esapi/crypto/KeyDerivationFunctionTest.java b/src/test/java/org/owasp/esapi/crypto/KeyDerivationFunctionTest.java new file mode 100644 index 000000000..3fdf7c8f4 --- /dev/null +++ b/src/test/java/org/owasp/esapi/crypto/KeyDerivationFunctionTest.java @@ -0,0 +1,209 @@ +package org.owasp.esapi.crypto; + +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; +import java.security.NoSuchAlgorithmException; +import java.security.InvalidKeyException; + +import static org.junit.Assert.*; +import org.junit.BeforeClass; +import org.junit.Before; +import org.junit.Test; + +import junit.framework.JUnit4TestAdapter; + +import org.owasp.esapi.crypto.KeyDerivationFunction; +import org.owasp.esapi.crypto.CryptoHelper; +import org.owasp.esapi.errors.EncryptionException; + +public class KeyDerivationFunctionTest { + + private static SecretKey desKey; + private static SecretKey tdes2key; + private static SecretKey tdes3key; + private static SecretKey aes128key; + private static SecretKey aes192key; + private static SecretKey aes256key; + private static SecretKey shortKey; + + private KeyDerivationFunction kdfSha1; + private KeyDerivationFunction kdfSha256; + + @BeforeClass + public static void setupStatic() { + try { + desKey = CryptoHelper.generateSecretKey("DES", 56); + tdes2key = CryptoHelper.generateSecretKey("DESede", 112); + tdes3key = CryptoHelper.generateSecretKey("DESede", 168); + aes128key = CryptoHelper.generateSecretKey("AES", 128); + aes128key = CryptoHelper.generateSecretKey("AES", 128); + aes192key = CryptoHelper.generateSecretKey("AES", 192); + aes256key = CryptoHelper.generateSecretKey("AES", 256); + + shortKey = new SecretKeySpec(desKey.getEncoded(), 0, 5, "Blowfish"); // 40-bits. Blowfish has var key size + } catch (EncryptionException e) { + fail("Caught unexpected EncryptionException while generating keys; msg was " + + e.getMessage()); + } + } + + @Before + public void setup() { + kdfSha1 = new KeyDerivationFunction( KeyDerivationFunction.PRF_ALGORITHMS.HmacSHA1 ); + kdfSha256 = new KeyDerivationFunction( KeyDerivationFunction.PRF_ALGORITHMS.HmacSHA256 ); + } + + @Test(expected = EncryptionException.class) + public void testKeyTooShort() throws EncryptionException { + // System.out.println("testKeyTooShort"); + try { + SecretKey key = kdfSha1.computeDerivedKey( shortKey, 128, "encryption" ); + fail("testKeyTooShort: Expected IllegalArgumentException to be thrown."); + } catch ( NoSuchAlgorithmException | InvalidKeyException e ) { + fail("Caught unexpected exception " + e.getClass().getName() + ": exception msg: " + e); + } + } + + @Test(expected = IllegalArgumentException.class) + public void testKeySizeTooShort() { + // System.out.println("testKeySizeTooShort"); + try { + SecretKey key = kdfSha1.computeDerivedKey( aes128key, 40, "encryption" ); // Min size is 56 bits + fail("testKeySizeTooShort: Expected IllegalArgumentException to be thrown."); + } catch ( NoSuchAlgorithmException | InvalidKeyException | EncryptionException e ) { + fail("Caught unexpected exception " + e.getClass().getName() + ": exception msg: " + e); + } + } + + @Test(expected = IllegalArgumentException.class) + public void testNullKey() { + // System.out.println("testNullKey"); + try { + SecretKey key = kdfSha1.computeDerivedKey( null, 56, "encryption" ); // Null key disallowed + assertTrue(key == null); // Not reached! + } catch ( NoSuchAlgorithmException | InvalidKeyException | EncryptionException e ) { + fail("Caught unexpected exception " + e.getClass().getName() + ": exception msg: " + e); + } + } + + @Test(expected = IllegalArgumentException.class) + public void testKeySizeNotEvenNumberOfBytes() { + // System.out.println("testKeySizeNotEvenNumberOfBytes"); + try { + SecretKey key = kdfSha1.computeDerivedKey( aes128key, 60, "encryption" ); // 60 % 8 == 4 + assertTrue(key == null); // Not reached! + } catch ( NoSuchAlgorithmException | InvalidKeyException | EncryptionException e ) { + fail("Caught unexpected exception " + e.getClass().getName() + ": exception msg: " + e); + } + } + + @Test(expected = IllegalArgumentException.class) + public void testPurposeNull() { + // System.out.println("testPurposeNull"); + try { + SecretKey key = kdfSha1.computeDerivedKey( aes128key, 128, null ); // purpose is null + assertTrue(key == null); // Not reached! + } catch ( NoSuchAlgorithmException | InvalidKeyException | EncryptionException e ) { + fail("Caught unexpected exception " + e.getClass().getName() + ": exception msg: " + e); + } + } + + @Test(expected = IllegalArgumentException.class) + public void testPurposeEmpty() { + // System.out.println("testPurposeEmpty"); + try { + SecretKey key = kdfSha1.computeDerivedKey( aes128key, 128, "" ); // purpose is empty string + assertTrue(key == null); // Not reached! + } catch ( NoSuchAlgorithmException | InvalidKeyException | EncryptionException e ) { + fail("Caught unexpected exception " + e.getClass().getName() + ": exception msg: " + e); + } + } + + @Test + public void testSunnyDay() { + // System.out.println("testSunnyDay"); + try { + SecretKey key1 = kdfSha1.computeDerivedKey( aes128key, 128, "encryption" ); + assertTrue(key1 != null); + assertTrue( key1.getEncoded().length == 128 / 8 ); + + SecretKey key2 = kdfSha1.computeDerivedKey( aes128key, 128, "authenticity" ); + assertTrue(key2 != null); + assertTrue( key2.getEncoded().length == 128 / 8 ); + + SecretKey key1b = kdfSha1.computeDerivedKey( aes128key, 128, "encryption" ); + + assertTrue( java.security.MessageDigest.isEqual( key1.getEncoded(), key1b.getEncoded() ) ); + assertFalse( java.security.MessageDigest.isEqual( key1.getEncoded(), key2.getEncoded() ) ); + } catch ( NoSuchAlgorithmException | InvalidKeyException | EncryptionException e ) { + fail("Caught unexpected exception " + e.getClass().getName() + ": exception msg: " + e); + } + } + + @Test + public void testSunnyDay2() { // Two sunny day tests in a row!? This inevitably will fail if run in Columbus, OH. + // System.out.println("testSunnyDay2"); + try { + SecretKey key1 = kdfSha256.computeDerivedKey( aes256key, 192, "Why am I here?" ); + assertTrue(key1 != null); + assertTrue( key1.getEncoded().length == 192 / 8 ); + + // Be honest. You thought I was goint to say "42", didn't you? + SecretKey key2 = kdfSha256.computeDerivedKey( aes256key, 192, "No doubt, to annoy people." ); + assertTrue(key2 != null); + assertTrue( key2.getEncoded().length == 192 / 8 ); + + // Should be different because different purpose given for each. + assertFalse( java.security.MessageDigest.isEqual( key1.getEncoded(), key2.getEncoded() ) ); + } catch ( NoSuchAlgorithmException | InvalidKeyException | EncryptionException e ) { + fail("Caught unexpected exception " + e.getClass().getName() + ": exception msg: " + e); + } + } + + @Test + public void testSetContext() { + // System.out.println("testSetContext"); + try { + SecretKey key1 = kdfSha256.computeDerivedKey( aes128key, 128, "encryption" ); + assertTrue(key1 != null); + assertTrue( key1.getEncoded().length == 128 / 8 ); + + SecretKey key2 = kdfSha1.computeDerivedKey( aes128key, 128, "encryption" ); + + // Should be false because one uses HmacSHA256 and the other uses HmacSHA1 + assertFalse( java.security.MessageDigest.isEqual( key1.getEncoded(), key2.getEncoded() ) ); + + kdfSha256.setContext( "plugh xyzzy" ); // Change context. Originally it is empty string. + SecretKey key1b = kdfSha256.computeDerivedKey( aes128key, 128, "encryption" ); + assertTrue(key1b != null); + assertTrue( key1b.getEncoded().length == 128 / 8 ); + + // Should be false because different contexts used. + assertFalse( java.security.MessageDigest.isEqual( key1.getEncoded(), key1b.getEncoded() ) ); + } catch ( NoSuchAlgorithmException | InvalidKeyException | EncryptionException e ) { + fail("Caught unexpected exception " + e.getClass().getName() + ": exception msg: " + e); + } + } + + @Test(expected = IllegalArgumentException.class) + public void testSetContextToNull() { + // System.out.println("testSetContextToNull"); + try { + SecretKey key1 = kdfSha256.computeDerivedKey( aes128key, 128, "encryption" ); + kdfSha256.setContext( null ); // Throws IllegalArgumentExeption + + fail("testSetContextToNull: Expected IllegalArgumentException to be thrown."); + } catch ( NoSuchAlgorithmException | InvalidKeyException | EncryptionException e ) { + fail("Caught unexpected exception " + e.getClass().getName() + ": exception msg: " + e); + } + } + + /** + * Run all the test cases in this suite. This is to allow running from + * {@code org.owasp.esapi.AllTests} which uses a JUnit 3 test runner. + */ + public static junit.framework.Test suite() { + // System.out.println("In suite()"); + return new JUnit4TestAdapter(KeyDerivationFunctionTest.class); + } +} diff --git a/src/test/java/org/owasp/esapi/crypto/PlainTextTest.java b/src/test/java/org/owasp/esapi/crypto/PlainTextTest.java new file mode 100644 index 000000000..3f65b2647 --- /dev/null +++ b/src/test/java/org/owasp/esapi/crypto/PlainTextTest.java @@ -0,0 +1,124 @@ +package org.owasp.esapi.crypto; + +import static org.junit.Assert.*; + +import java.io.UnsupportedEncodingException; +import java.util.Arrays; + +import junit.framework.JUnit4TestAdapter; +import org.junit.Test; +import org.owasp.esapi.crypto.PlainText; + +public class PlainTextTest { + + private String unicodeStr = "A\u00ea\u00f1\u00fcC"; // I.e., "AêñüC" + private String altString = "AêñüC"; // Same as above. + + /* NOTE: This test will not work on Windows unless executed under + * Eclipse and the file is stored / treated as a UTF-8 encoded file + * rather than the Windows native OS encoding of Windows-1252 (aka, + * CP-1252). Therefore this test case has a check to not run the test + * unless + * unicodeStr.equals(altString) + * is true. If not the test is skipped and a message is printed to stderr. + * Jim Manico made an attempt to address this (see private email to + * kevin.w.wall@gmail.com on 11/26/2009, subject "Re: [OWASP-ESAPI] Unit + * Tests Status") to correct this problem by setting some SVN attribute + * to standardize all source files to UTF-8, but not all Subversion clients + * are either honoring this or perhaps Windows just overrides this. Either + * way, this test (which used to be an assertTrue() expression) was + * introduced to account for this. + */ + @Test + public final void testUnicodeString() { + // These 2 strings are *meant* to be equal. If they are not, please + // do *NOT* change the test. It's a Windows thing. Sorry. Change your + // OS instead. ;-) + if ( ! unicodeStr.equals(altString) ) { + System.err.println("Skipping JUnit test case " + + "PlainTextTest.testUnicodeString() on OS " + + System.getProperty("os.name") ); + return; + } + try { + byte[] utf8Bytes = unicodeStr.getBytes("UTF-8"); + PlainText pt1 = new PlainText(unicodeStr); + PlainText pt2 = new PlainText(altString); + + assertTrue( pt1.equals(pt1) ); // Equals self + assertFalse( pt1.equals(null) ); + assertTrue( pt1.equals(pt2) ); + assertFalse( pt1.equals( unicodeStr ) ); + assertTrue( pt1.length() == utf8Bytes.length ); + assertTrue( Arrays.equals(utf8Bytes, pt1.asBytes()) ); + assertTrue( pt1.hashCode() == unicodeStr.hashCode() ); + + } catch (UnsupportedEncodingException e) { + fail("No UTF-8 byte encoding: " + e); + e.printStackTrace(System.err); + } + } + + @Test + public final void testNullCase() { + int counter = 0; + try { + byte[] bytes = null; + PlainText pt = new PlainText(bytes); + fail("testNullCase(): Expected IllegalArgumentException"); + } catch (IllegalArgumentException e) { + ; // Success + } catch (Exception e) { + fail("testNullCase(): Caught unexpected exception: " + e); + } + } + + @Test + public final void testEmptyString() { + PlainText mt = new PlainText(""); + assertTrue( mt.length() == 0 ); + byte[] ba = mt.asBytes(); + assertTrue( ba != null && ba.length == 0 ); + } + + @Test + public final void testOverwrite() { + try { + byte[] origBytes = unicodeStr.getBytes("UTF-8"); + PlainText pt = new PlainText(origBytes); + assertTrue( pt.toString().equals(unicodeStr) ); + assertTrue( Arrays.equals(origBytes, pt.asBytes()) ); + assertTrue( pt.hashCode() == unicodeStr.hashCode() ); + + int origLen = origBytes.length; + + pt.overwrite(); + byte[] overwrittenBytes = pt.asBytes(); + assertTrue( overwrittenBytes != null ); + assertFalse( Arrays.equals( origBytes, overwrittenBytes ) ); + + // Ensure that ALL the bytes overwritten with '*'. + int afterLen = overwrittenBytes.length; + assertTrue( origLen == afterLen ); + int sum = 0; + for( int i = 0; i < afterLen; i++ ) { + if ( overwrittenBytes[i] == '*' ) { + sum++; + } + } + assertTrue( afterLen == sum ); + } catch (UnsupportedEncodingException e) { + fail("No UTF-8 byte encoding: " + e); + e.printStackTrace(System.err); + } + } + + /** + * Run all the test cases in this suite. + * This is to allow running from {@code org.owasp.esapi.AllTests} which + * uses a JUnit 3 test runner. + */ + public static junit.framework.Test suite() { + return new JUnit4TestAdapter(PlainTextTest.class); + } +} diff --git a/src/test/java/org/owasp/esapi/crypto/SecurityProviderLoaderTest.java b/src/test/java/org/owasp/esapi/crypto/SecurityProviderLoaderTest.java new file mode 100644 index 000000000..441b07bd9 --- /dev/null +++ b/src/test/java/org/owasp/esapi/crypto/SecurityProviderLoaderTest.java @@ -0,0 +1,139 @@ +package org.owasp.esapi.crypto; + +import static org.junit.Assert.*; + +import java.security.NoSuchProviderException; +import java.security.Provider; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.errors.EncryptionException; + +/** + * Test for class {@code SecurityProviderLoader}. Note that these tests + * use Bouncy Castle's JCE provider so a version their jar must be added + * to your class path. If you wish to add it via Maven, you can do so by + * adding this to your pom.xml: + *
+ * 
+ *      org.bouncycastle
+ *      bcprov-jdk15
+ *      1.44
+ * 
+ * 
+ * It has been tested with Bouncy Castle 1.44, but any later version should + * do as well. + * @author kevin.w.wall@gmail.com + */ +public class SecurityProviderLoaderTest { + + private static boolean HAS_BOUNCY_CASTLE = false; + + @BeforeClass + public static void setUpBeforeClass() { + try { + Class providerClass = Class.forName("org.bouncycastle.jce.provider.BouncyCastleProvider"); + Provider cryptoProvider = (Provider)providerClass.newInstance(); + assertTrue( cryptoProvider != null ); + HAS_BOUNCY_CASTLE = true; + } catch(Exception ex) { + // Note: FindBugs reports a false positive here... + // REC_CATCH_EXCEPTION: Exception is caught when Exception is not thrown + // but exceptions really can be thrown. + HAS_BOUNCY_CASTLE = false; + } + } + + @Test + public final void testInsertProviderAt() { + if ( ! HAS_BOUNCY_CASTLE ) { + System.out.println("SecurityProviderLoaderTest.testInsertProviderAt(): " + + "Skipping test -- must have Bouncy Castle JCE provider in classpath."); + return; + } + + try { + SecurityProviderLoader.insertProviderAt("BC", 1); + assertTrue(true); + } catch (NoSuchProviderException e) { + fail("Caught NoSuchProviderException trying to load Bouncy Castle; exception was: " + e); + } + } + + @Test + public final void testLoadESAPIPreferredJCEProvider() { + // Note: OK if empty string or unset, in fact default is empty string. + String preferredProvider = ESAPI.securityConfiguration().getPreferredJCEProvider(); + try { + SecurityProviderLoader.loadESAPIPreferredJCEProvider(); + assertTrue(true); + } catch (NoSuchProviderException e) { + fail("Caught NoSuchProviderException trying to preferred JCE provider " + + preferredProvider + "; exception was: " + e); + } + } + + @Test(expected=NoSuchProviderException.class) + public final void testNoSuchProviderException() throws NoSuchProviderException { + SecurityProviderLoader.insertProviderAt("DrBobsSecretSnakeOilElixirCryptoJCE", 5); + } + + @Test(expected=NoSuchProviderException.class) + public final void testBogusProviderWithFQCN() throws NoSuchProviderException { + SecurityProviderLoader.insertProviderAt("com.snakeoil.DrBobsSecretSnakeOilElixirCryptoJCE", 5); + } + + @Test + public final void testWithBouncyCastle() { + if ( ! HAS_BOUNCY_CASTLE ) { + System.out.println("SecurityProviderLoaderTest.testInsertProviderAt(): " + + "Skipping test -- must have Bouncy Castle JCE provider in classpath."); + return; + } + + try { + SecurityProviderLoader.insertProviderAt("BC", 1); + assertTrue(true); + } catch (NoSuchProviderException e) { + fail("Caught NoSuchProviderException trying to load Bouncy Castle; exception was: " + e); + } + + // First encrypt w/ preferred cipher transformation (AES/CBC/PKCS5Padding). + try { + PlainText clearMsg = new PlainText("This is top secret! We are all out of towels!"); + String origMsg = clearMsg.toString(); // Must keep 'cuz by default, clearMsg is overwritten. + CipherText ct = ESAPI.encryptor().encrypt(clearMsg); + assertEquals( "*********************************************", clearMsg.toString() ); + PlainText plain = ESAPI.encryptor().decrypt(ct); + assertEquals( origMsg, plain.toString() ); + } catch (EncryptionException e) { + fail("Encryption w/ Bouncy Castle failed with EncryptionException for preferred " + + "cipher transformation; exception was: " + e); + } + + // Next, try a "combined mode" cipher mode available in Bouncy Castle. + String origCipherXform = null; + try { + origCipherXform = ESAPI.securityConfiguration().setCipherTransformation("AES/GCM/NoPadding"); + PlainText clearMsg = new PlainText("This is top secret! We are all out of towels!"); + String origMsg = clearMsg.toString(); // Must keep 'cuz by default, clearMsg is overwritten. + CipherText ct = ESAPI.encryptor().encrypt(clearMsg); + PlainText plain = ESAPI.encryptor().decrypt(ct); + assertEquals( origMsg, plain.toString() ); + // Verify that no MAC is calculated for GCM cipher mode. There is no method to + // validate this, so we look at the String representation of this CipherText + // object and pick it out of there. + String str = ct.toString(); + assertTrue( str.matches(".*; MAC is absent;.*") ); + } catch (EncryptionException e) { + fail("Encryption w/ Bouncy Castle failed with EncryptionException for preferred " + + "cipher transformation; exception was: " + e); + } finally { + ESAPI.securityConfiguration().setCipherTransformation(origCipherXform); + } + } +} diff --git a/test/org/owasp/esapi/errors/EnterpriseSecurityExceptionTest.java b/src/test/java/org/owasp/esapi/errors/EnterpriseSecurityExceptionTest.java similarity index 88% rename from test/org/owasp/esapi/errors/EnterpriseSecurityExceptionTest.java rename to src/test/java/org/owasp/esapi/errors/EnterpriseSecurityExceptionTest.java index 236fd4412..a5a6de707 100644 --- a/test/org/owasp/esapi/errors/EnterpriseSecurityExceptionTest.java +++ b/src/test/java/org/owasp/esapi/errors/EnterpriseSecurityExceptionTest.java @@ -1,150 +1,157 @@ -/** - * 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.errors; - -import org.owasp.esapi.errors.AccessControlException; -import org.owasp.esapi.errors.AuthenticationAccountsException; -import org.owasp.esapi.errors.AuthenticationCredentialsException; -import org.owasp.esapi.errors.AuthenticationException; -import org.owasp.esapi.errors.AuthenticationHostException; -import org.owasp.esapi.errors.AuthenticationLoginException; -import org.owasp.esapi.errors.AvailabilityException; -import org.owasp.esapi.errors.CertificateException; -import org.owasp.esapi.errors.EncodingException; -import org.owasp.esapi.errors.EncryptionException; -import org.owasp.esapi.errors.EnterpriseSecurityException; -import org.owasp.esapi.errors.ExecutorException; -import org.owasp.esapi.errors.IntegrityException; -import org.owasp.esapi.errors.IntrusionException; -import org.owasp.esapi.errors.ValidationAvailabilityException; -import org.owasp.esapi.errors.ValidationException; -import org.owasp.esapi.errors.ValidationUploadException; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -/** - * The Class AccessReferenceMapTest. - * - * @author Jeff Williams (jeff.williams@aspectsecurity.com) - */ -public class EnterpriseSecurityExceptionTest extends TestCase { - - /** - * Instantiates a new access reference map test. - * - * @param testName - * the test name - */ - public EnterpriseSecurityExceptionTest(String testName) { - super(testName); - } - - /* (non-Javadoc) - * @see junit.framework.TestCase#setUp() - */ - protected void setUp() throws Exception { - // none - } - - /* (non-Javadoc) - * @see junit.framework.TestCase#tearDown() - */ - protected void tearDown() throws Exception { - // none - } - - /** - * Suite. - * - * @return the test - */ - public static Test suite() { - TestSuite suite = new TestSuite(EnterpriseSecurityExceptionTest.class); - return suite; - } - - - /** - * Test of update method, of class org.owasp.esapi.AccessReferenceMap. - * - * @throws AuthenticationException - * the authentication exception - */ - public void testExceptions() { - System.out.println("exceptions"); - EnterpriseSecurityException e = null; - e = new EnterpriseSecurityException(); - e = new EnterpriseSecurityException("m1","m2"); - e = new EnterpriseSecurityException("m1","m2",new Throwable()); - assertEquals( e.getUserMessage(), "m1" ); - assertEquals( e.getLogMessage(), "m2" ); - e = new AccessControlException(); - e = new AccessControlException("m1","m2"); - e = new AccessControlException("m1","m2",new Throwable()); - e = new AuthenticationException(); - e = new AuthenticationException("m1","m2"); - e = new AuthenticationException("m1","m2",new Throwable()); - e = new AvailabilityException(); - e = new AvailabilityException("m1","m2"); - e = new AvailabilityException("m1","m2",new Throwable()); - e = new CertificateException(); - e = new CertificateException("m1","m2"); - e = new CertificateException("m1","m2",new Throwable()); - e = new EncodingException(); - e = new EncodingException("m1","m2"); - e = new EncodingException("m1","m2",new Throwable()); - e = new EncryptionException(); - e = new EncryptionException("m1","m2"); - e = new EncryptionException("m1","m2",new Throwable()); - e = new ExecutorException(); - e = new ExecutorException("m1","m2"); - e = new ExecutorException("m1","m2",new Throwable()); - e = new ValidationException(); - e = new ValidationException("m1","m2"); - e = new ValidationException("m1","m2",new Throwable()); - e = new IntegrityException(); - e = new IntegrityException("m1","m2"); - e = new IntegrityException("m1","m2",new Throwable()); - e = new AuthenticationHostException(); - e = new AuthenticationHostException("m1","m2"); - e = new AuthenticationHostException("m1","m2",new Throwable()); - - e = new AuthenticationAccountsException(); - e = new AuthenticationAccountsException("m1","m2"); - e = new AuthenticationAccountsException("m1","m2",new Throwable()); - e = new AuthenticationCredentialsException(); - e = new AuthenticationCredentialsException("m1","m2"); - e = new AuthenticationCredentialsException("m1","m2",new Throwable()); - e = new AuthenticationLoginException(); - e = new AuthenticationLoginException("m1","m2"); - e = new AuthenticationLoginException("m1","m2",new Throwable()); - e = new ValidationAvailabilityException(); - e = new ValidationAvailabilityException("m1","m2"); - e = new ValidationAvailabilityException("m1","m2",new Throwable()); - e = new ValidationUploadException(); - e = new ValidationUploadException("m1","m2"); - e = new ValidationUploadException("m1","m2",new Throwable()); - - IntrusionException ex = new IntrusionException( "test", "test details"); - ex = new IntrusionException("m1","m2"); - ex = new IntrusionException("m1","m2", new Throwable()); - assertEquals( ex.getUserMessage(), "m1" ); - assertEquals( ex.getLogMessage(), "m2" ); - } - -} +/** + * 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.errors; + +import org.owasp.esapi.errors.AccessControlException; +import org.owasp.esapi.errors.AuthenticationAccountsException; +import org.owasp.esapi.errors.AuthenticationCredentialsException; +import org.owasp.esapi.errors.AuthenticationException; +import org.owasp.esapi.errors.AuthenticationHostException; +import org.owasp.esapi.errors.AuthenticationLoginException; +import org.owasp.esapi.errors.AvailabilityException; +import org.owasp.esapi.errors.CertificateException; +import org.owasp.esapi.errors.EncodingException; +import org.owasp.esapi.errors.EncryptionException; +import org.owasp.esapi.errors.EnterpriseSecurityException; +import org.owasp.esapi.errors.ExecutorException; +import org.owasp.esapi.errors.IntegrityException; +import org.owasp.esapi.errors.IntrusionException; +import org.owasp.esapi.errors.ValidationAvailabilityException; +import org.owasp.esapi.errors.ValidationException; +import org.owasp.esapi.errors.ValidationUploadException; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * The Class AccessReferenceMapTest. + * + * @author Jeff Williams (jeff.williams@aspectsecurity.com) + */ +public class EnterpriseSecurityExceptionTest extends TestCase { + + /** + * Instantiates a new access reference map test. + * + * @param testName + * the test name + */ + public EnterpriseSecurityExceptionTest(String testName) { + super(testName); + } + + /** + * {@inheritDoc} + * @throws Exception + */ + protected void setUp() throws Exception { + // none + } + + /** + * {@inheritDoc} + * @throws Exception + */ + protected void tearDown() throws Exception { + // none + } + + /** + * Suite. + * + * @return the test + */ + public static Test suite() { + TestSuite suite = new TestSuite(EnterpriseSecurityExceptionTest.class); + return suite; + } + + + /** + * Test of update method, of class org.owasp.esapi.AccessReferenceMap. + * + */ + public void testExceptions() { + System.out.println("exceptions"); + EnterpriseSecurityException e = null; + e = new EnterpriseSecurityException(); + e = new EnterpriseSecurityException("m1","m2"); + e = new EnterpriseSecurityException("m1","m2",new Throwable()); + assertEquals( e.getUserMessage(), "m1" ); + assertEquals( e.getLogMessage(), "m2" ); + e = new AccessControlException(); + e = new AccessControlException("m1","m2"); + e = new AccessControlException("m1","m2",new Throwable()); + e = new AuthenticationException(); + e = new AuthenticationException("m1","m2"); + e = new AuthenticationException("m1","m2",new Throwable()); + e = new AvailabilityException(); + e = new AvailabilityException("m1","m2"); + e = new AvailabilityException("m1","m2",new Throwable()); + e = new CertificateException(); + e = new CertificateException("m1","m2"); + e = new CertificateException("m1","m2",new Throwable()); + e = new EncodingException(); + e = new EncodingException("m1","m2"); + e = new EncodingException("m1","m2",new Throwable()); + e = new EncryptionException(); + e = new EncryptionException("m1","m2"); + e = new EncryptionException("m1","m2",new Throwable()); + e = new ExecutorException(); + e = new ExecutorException("m1","m2"); + e = new ExecutorException("m1","m2",new Throwable()); + e = new ValidationException(); + e = new ValidationException("m1","m2"); + e = new ValidationException("m1","m2",new Throwable()); + e = new ValidationException("m1","m2","context"); + e = new ValidationException("m1","m2",new Throwable(),"context"); + + e = new IntegrityException(); + e = new IntegrityException("m1","m2"); + e = new IntegrityException("m1","m2",new Throwable()); + e = new AuthenticationHostException(); + e = new AuthenticationHostException("m1","m2"); + e = new AuthenticationHostException("m1","m2",new Throwable()); + + e = new AuthenticationAccountsException(); + e = new AuthenticationAccountsException("m1","m2"); + e = new AuthenticationAccountsException("m1","m2",new Throwable()); + e = new AuthenticationCredentialsException(); + e = new AuthenticationCredentialsException("m1","m2"); + e = new AuthenticationCredentialsException("m1","m2",new Throwable()); + e = new AuthenticationLoginException(); + e = new AuthenticationLoginException("m1","m2"); + e = new AuthenticationLoginException("m1","m2",new Throwable()); + e = new ValidationAvailabilityException(); + e = new ValidationAvailabilityException("m1","m2"); + e = new ValidationAvailabilityException("m1","m2",new Throwable()); + e = new ValidationUploadException(); + e = new ValidationUploadException("m1","m2"); + e = new ValidationUploadException("m1","m2",new Throwable()); + + ValidationException ve = new ValidationException(); + ve.setContext("test"); + assertEquals( "test", ve.getContext() ); + + IntrusionException ex = new IntrusionException( "test", "test details"); + ex = new IntrusionException("m1","m2"); + ex = new IntrusionException("m1","m2", new Throwable()); + assertEquals( ex.getUserMessage(), "m1" ); + assertEquals( ex.getLogMessage(), "m2" ); + } + +} diff --git a/src/test/java/org/owasp/esapi/filters/ClickjackFilterTest.java b/src/test/java/org/owasp/esapi/filters/ClickjackFilterTest.java new file mode 100644 index 000000000..369e3f881 --- /dev/null +++ b/src/test/java/org/owasp/esapi/filters/ClickjackFilterTest.java @@ -0,0 +1,106 @@ +/** + * 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.filters; + +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.FilterConfig; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.owasp.esapi.http.MockFilterChain; +import org.owasp.esapi.http.MockFilterConfig; +import org.owasp.esapi.http.MockHttpServletRequest; +import org.owasp.esapi.http.MockHttpServletResponse; + +/** + * The Class ClickjackFilterTest. + * + * @author Jeff Williams (jeff.williams@aspectsecurity.com) + */ +public class ClickjackFilterTest extends TestCase { + + /** + * @param testName + * the test name + */ + public ClickjackFilterTest(String testName) { + super(testName); + } + + /** + * {@inheritDoc} + * @throws Exception + */ + protected void setUp() throws Exception { + // none + } + + /** + * {@inheritDoc} + * @throws Exception + */ + protected void tearDown() throws Exception { + // none + } + + /** + * Suite. + * + * @return the test + */ + public static Test suite() { + TestSuite suite = new TestSuite(ClickjackFilterTest.class); + return suite; + } + + + /** + * Test of update method, of class org.owasp.esapi.AccessReferenceMap. + * @throws Exception + */ + public void testFilter() throws Exception { + System.out.println("ClickjackFilter"); + + Map map = new HashMap(); + FilterConfig mfc = new MockFilterConfig( map ); + ClickjackFilter filter = new ClickjackFilter(); + filter.init( mfc ); + MockHttpServletRequest request = new MockHttpServletRequest(); + + // the mock filter chain writes the requested URI to the response body + MockFilterChain chain = new MockFilterChain(); + + URL url = new URL( "http://www.example.com/index.jsp" ); + System.out.println( "\nTest request: " + url ); + request = new MockHttpServletRequest( url ); + MockHttpServletResponse response = new MockHttpServletResponse(); + try { + filter.doFilter(request, response, chain); + } catch( Exception e ) { + e.printStackTrace(); + fail(); + } + String header = response.getHeader( "X-FRAME-OPTIONS"); + System.out.println(">>>" + header ); + assertEquals( "DENY", header ); + } + +} diff --git a/src/test/java/org/owasp/esapi/filters/SafeRequestTest.java b/src/test/java/org/owasp/esapi/filters/SafeRequestTest.java new file mode 100644 index 000000000..11e45b651 --- /dev/null +++ b/src/test/java/org/owasp/esapi/filters/SafeRequestTest.java @@ -0,0 +1,140 @@ +/** + * 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.filters; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.owasp.esapi.http.MockHttpServletRequest; + + +/** + * The Class SafeRequestTest. + * + * @author Jeff Williams (jeff.williams@aspectsecurity.com) + */ +public class SafeRequestTest extends TestCase { + + /** + * Instantiates a new access controller test. + * + * @param testName + * the test name + * @throws Exception + */ + public SafeRequestTest(String testName) throws Exception { + super(testName); + } + + /** + * {@inheritDoc} + * + * @throws Exception + */ + protected void setUp() throws Exception { + } + + /** + * {@inheritDoc} + * + * @throws Exception + */ + protected void tearDown() throws Exception { + // none + } + + /** + * Suite. + * + * @return the test + */ + public static Test suite() { + TestSuite suite = new TestSuite(SafeRequestTest.class); + return suite; + } + + /** + * + */ + public void testGetRequestParameters() { + System.out.println( "getRequestParameters"); + MockHttpServletRequest request = new MockHttpServletRequest(); + request.addParameter( "one","1" ); + request.addParameter( "two","2" ); + request.addParameter( "one","3" ); + request.addParameter( "one","4" ); + SecurityWrapperRequest safeRequest = new SecurityWrapperRequest( request ); + String[] params = safeRequest.getParameterValues("one"); + String out = ""; + for (int i = 0; i < params.length; i++ ) out += params[i]; + assertEquals( "134", out ); + } + + public void testGetQueryStringNull() + { + MockHttpServletRequest req = new MockHttpServletRequest(); + SecurityWrapperRequest wrappedReq; + + req.setQueryString(null); + wrappedReq = new SecurityWrapperRequest(req); + assertNull(wrappedReq.getQueryString()); + } + + // Test to ensure null-value contract defined by ServletRequest.getParameterNames(String) is met. + public void testGetParameterValuesReturnsNullWhenParameterDoesNotExistInRequest() { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.clearParameters(); + + final String paramName = "nonExistentParameter"; + assertNull(request.getParameterValues(paramName)); + + SecurityWrapperRequest safeRequest = new SecurityWrapperRequest(request); + assertNull("Expecting null value to be returned for non-existent parameter.", safeRequest.getParameterValues(paramName)); + } + + public void testGetParameterValuesReturnsCorrectValueWhenParameterExistsInRequest() { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.clearParameters(); + + final String paramName = "existentParameter"; + final String paramValue = "foobar"; + request.addParameter(paramName, paramValue); + assertTrue(request.getParameterValues(paramName)[0].equals(paramValue)); + + SecurityWrapperRequest safeRequest = new SecurityWrapperRequest(request); + final String actualParamValue = safeRequest.getParameterValues(paramName)[0]; + assertEquals(paramValue, actualParamValue); + } + + public void testGetParameterValuesReturnsCorrectValuesWhenParameterExistsMultipleTimesInRequest() { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.clearParameters(); + + final String paramName = "existentParameter"; + final String paramValue_0 = "foobar"; + final String paramValue_1 = "barfoo"; + request.addParameter(paramName, paramValue_0); + request.addParameter(paramName, paramValue_1); + assertTrue(request.getParameterValues(paramName)[0].equals(paramValue_0)); + assertTrue(request.getParameterValues(paramName)[1].equals(paramValue_1)); + + SecurityWrapperRequest safeRequest = new SecurityWrapperRequest(request); + final String[] actualParamValues = safeRequest.getParameterValues(paramName); + assertEquals(paramValue_0, actualParamValues[0]); + assertEquals(paramValue_1, actualParamValues[1]); + } +} diff --git a/src/test/java/org/owasp/esapi/filters/SecurityWrapperRequestTest.java b/src/test/java/org/owasp/esapi/filters/SecurityWrapperRequestTest.java new file mode 100644 index 000000000..40c9d36da --- /dev/null +++ b/src/test/java/org/owasp/esapi/filters/SecurityWrapperRequestTest.java @@ -0,0 +1,667 @@ +/** + * 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-2018 - 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.filters; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.owasp.esapi.PropNames.DISABLE_INTRUSION_DETECTION; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestName; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.ArgumentMatchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Logger; +import org.owasp.esapi.SecurityConfiguration; +import org.owasp.esapi.Validator; +import org.owasp.esapi.errors.ValidationException; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +/** + * Unit tests for {@link SecurityWrapperRequest}. + *
+ * This test uses static context mocking! This can affect certain behaviors if it is executed in a JVM container with + * other tests depending on the same static reference - Which is going to be everything. + *
+ * This may affect some test environments, mostly IDE's. It is not expected that this impacts the Maven build, as + * surefire plugin isolates JVM's for tests during that phase. + */ +@RunWith(PowerMockRunner.class) +@PrepareForTest(ESAPI.class) +public class SecurityWrapperRequestTest { + protected static final String ESAPI_VALIDATOR_GETTER_METHOD_NAME = "validator"; + protected static final String ESAPI_GET_LOGGER_METHOD_NAME = "getLogger"; + protected static final String ESAPY_SECURITY_CONFIGURATION_GETTER_METHOD_NAME = "securityConfiguration"; + protected static final String SECURITY_CONFIGURATION_QUERY_STRING_LENGTH_KEY_NAME = "HttpUtilities.URILENGTH"; + protected static final String SECURITY_CONFIGURATION_PARAMETER_STRING_LENGTH_KEY_NAME = "HttpUtilities.httpQueryParamValueLength"; + private static final String SECURITY_CONFIGURATION_HEADER_NAME_LENGTH_KEY_NAME = "HttpUtilities.MaxHeaderNameSize"; + private static final String SECURITY_CONFIGURATION_HEADER_VALUE_LENGTH_KEY_NAME = "HttpUtilities.MaxHeaderValueSize"; + + protected static final int SECURITY_CONFIGURATION_TEST_LENGTH = 255; + + private static final String QUERY_STRING_CANONCALIZE_TYPE_KEY = "HTTPQueryString"; + private static final String PARAMETER_STRING_CANONCALIZE_TYPE_KEY = "HTTPParameterValue"; + private static final String COOKIE_NAME_TYPE_KEY = "HTTPCookieName"; + private static final String COOKIE_VALUE_TYPE_KEY = "HTTPCookieValue"; + private static final String COOKIE_DOMAIN_TYPE_KEY = "HTTPHeaderValue"; + private static final String COOKIE_PATH_TYPE_KEY = "HTTPHeaderValue"; + + @Rule + public TestName testName = new TestName(); + + @Mock + private HttpServletRequest mockRequest; + @Mock + private Validator mockValidator; + @Mock + private SecurityConfiguration mockSecConfig; + @Mock + private Logger mockLogger; + + private String testQueryValue; + private String testParameterName; + private String testParameterValue; + private String testValueCanonical; + private String testValidatorType; + private int testMaximumLength; + + @Before + public void setup() throws Exception { + PowerMockito.mockStatic(ESAPI.class); + PowerMockito.when(ESAPI.class, ESAPI_VALIDATOR_GETTER_METHOD_NAME).thenReturn(mockValidator); + PowerMockito.when(ESAPI.class, ESAPI_GET_LOGGER_METHOD_NAME, "SecurityWrapperRequest").thenReturn(mockLogger); + PowerMockito.when(ESAPI.class, ESAPY_SECURITY_CONFIGURATION_GETTER_METHOD_NAME).thenReturn(mockSecConfig); + //Is intrusion detection disabled? A: Yes, it is off. + //This logic is confusing: True, the value is False... + Mockito.when( mockSecConfig.getBooleanProp( DISABLE_INTRUSION_DETECTION ) ).thenReturn(true); + + testQueryValue = testName.getMethodName() + "_query_value"; + + testParameterName = testName.getMethodName() + "_parameter_name"; + testParameterValue = testName.getMethodName() + "_parameter_value"; + testValueCanonical = testName.getMethodName() + "_value_canonical"; + testValidatorType = testName.getMethodName() + "_validator_type"; + testMaximumLength = testName.getMethodName().length(); + } + + /** + * Workflow test for happy-path getQueryString. Asserts delegation calls and parameters to delegate + * behaviors. + */ + @Test + public void testGetQueryString() throws Exception { + ValidatorTestContainer validatorTester = new ValidatorTestContainer(mockValidator); + validatorTester.getValidInputReturns(testValueCanonical); + + PowerMockito.when(mockSecConfig.getIntProp(SECURITY_CONFIGURATION_QUERY_STRING_LENGTH_KEY_NAME)).thenReturn( + SECURITY_CONFIGURATION_TEST_LENGTH); + + PowerMockito.when(mockRequest.getQueryString()).thenReturn(testQueryValue); + + SecurityWrapperRequest request = new SecurityWrapperRequest(mockRequest); + String rval = request.getQueryString(); + assertEquals(testValueCanonical, rval); + + validatorTester.verify(testQueryValue, QUERY_STRING_CANONCALIZE_TYPE_KEY, SECURITY_CONFIGURATION_TEST_LENGTH, true); + + verify(mockSecConfig, times(1)).getIntProp(SECURITY_CONFIGURATION_QUERY_STRING_LENGTH_KEY_NAME); + verify(mockRequest, times(1)).getQueryString(); + } + + /** + * Test for getQueryString when validation throws an Exception. + *
+ * Asserts delegation calls and parameters to delegate behaviors. + */ + @Test + public void testGetQueryStringCanonicalizeException() throws Exception { + ValidatorTestContainer validatorTester = new ValidatorTestContainer(mockValidator); + validatorTester.getValidInputThrows(); + + PowerMockito.when(mockSecConfig.getIntProp(SECURITY_CONFIGURATION_QUERY_STRING_LENGTH_KEY_NAME)).thenReturn( + SECURITY_CONFIGURATION_TEST_LENGTH); + + PowerMockito.when(mockRequest.getQueryString()).thenReturn(testQueryValue); + + SecurityWrapperRequest request = new SecurityWrapperRequest(mockRequest); + String rval = request.getQueryString(); + + assertTrue("SecurityWrapperRequest should return an empty String when an exception occurs in validation", rval + .isEmpty()); + + validatorTester.verify(testQueryValue, QUERY_STRING_CANONCALIZE_TYPE_KEY, SECURITY_CONFIGURATION_TEST_LENGTH, true); + + verify(mockSecConfig, times(1)).getIntProp(SECURITY_CONFIGURATION_QUERY_STRING_LENGTH_KEY_NAME); + verify(mockRequest, times(1)).getQueryString(); + } + @Test + public void testGetParameterString() throws Exception{ + ValidatorTestContainer validatorTester = new ValidatorTestContainer(mockValidator); + validatorTester.getValidInputReturns(testValueCanonical); + + PowerMockito.when(mockSecConfig.getIntProp(SECURITY_CONFIGURATION_PARAMETER_STRING_LENGTH_KEY_NAME)).thenReturn( + SECURITY_CONFIGURATION_TEST_LENGTH); + + PowerMockito.when(mockRequest.getParameter(testParameterName)).thenReturn(testParameterValue); + + SecurityWrapperRequest request = new SecurityWrapperRequest(mockRequest); + String rval = request.getParameter(testParameterName); + assertEquals(testValueCanonical, rval); + + validatorTester.verify(testParameterValue, PARAMETER_STRING_CANONCALIZE_TYPE_KEY, SECURITY_CONFIGURATION_TEST_LENGTH, true); + + verify(mockSecConfig, times(1)).getIntProp(SECURITY_CONFIGURATION_PARAMETER_STRING_LENGTH_KEY_NAME); + verify(mockRequest, times(1)).getParameter(testParameterName); + } + + @Test + public void testGetParameterStringBoolean() throws Exception{ + ValidatorTestContainer validatorTester = new ValidatorTestContainer(mockValidator); + validatorTester.getValidInputReturns(testValueCanonical); + PowerMockito.when(mockSecConfig.getIntProp(SECURITY_CONFIGURATION_PARAMETER_STRING_LENGTH_KEY_NAME)).thenReturn( + SECURITY_CONFIGURATION_TEST_LENGTH); + + PowerMockito.when(mockRequest.getParameter(testParameterName)).thenReturn(testParameterValue); + + SecurityWrapperRequest request = new SecurityWrapperRequest(mockRequest); + String rval = request.getParameter(testParameterName, false); + assertEquals(testValueCanonical, rval); + + validatorTester.verify(testParameterValue, PARAMETER_STRING_CANONCALIZE_TYPE_KEY, SECURITY_CONFIGURATION_TEST_LENGTH, false); + + verify(mockSecConfig, times(1)).getIntProp(SECURITY_CONFIGURATION_PARAMETER_STRING_LENGTH_KEY_NAME); + verify(mockRequest, times(1)).getParameter(testParameterName); + } + + @Test + public void testGetParameterStringBooleanInt() throws Exception{ + ValidatorTestContainer validatorTester = new ValidatorTestContainer(mockValidator); + validatorTester.getValidInputReturns(testValueCanonical); + + PowerMockito.when(mockRequest.getParameter(testParameterName)).thenReturn(testParameterValue); + + SecurityWrapperRequest request = new SecurityWrapperRequest(mockRequest); + String rval = request.getParameter(testParameterName, false, testMaximumLength); + assertEquals(testValueCanonical, rval); + + validatorTester.verify(testParameterValue, PARAMETER_STRING_CANONCALIZE_TYPE_KEY, testMaximumLength, false); + + verify(mockRequest, times(1)).getParameter(testParameterName); + } + + @Test + public void testGetParameterStringBooleanIntString() throws Exception{ + ValidatorTestContainer validatorTester = new ValidatorTestContainer(mockValidator); + validatorTester.getValidInputReturns(testValueCanonical); + + + PowerMockito.when(mockRequest.getParameter(testParameterName)).thenReturn(testParameterValue); + + SecurityWrapperRequest request = new SecurityWrapperRequest(mockRequest); + String rval = request.getParameter(testParameterName, false, testMaximumLength, testValidatorType); + assertEquals(testValueCanonical, rval); + + validatorTester.verify(testParameterValue, testValidatorType, testMaximumLength, false); + + verify(mockRequest, times(1)).getParameter(testParameterName); + } + + + @Test + public void testGetParameterStringNullEvalPassthrough() throws Exception{ + ValidatorTestContainer validatorTester = new ValidatorTestContainer(mockValidator); + validatorTester.getValidInputReturns(null); + + PowerMockito.when(mockSecConfig.getIntProp(SECURITY_CONFIGURATION_PARAMETER_STRING_LENGTH_KEY_NAME)).thenReturn( + SECURITY_CONFIGURATION_TEST_LENGTH); + + PowerMockito.when(mockRequest.getParameter(testParameterName)).thenReturn(testParameterValue); + + SecurityWrapperRequest request = new SecurityWrapperRequest(mockRequest); + String rval = request.getParameter(testParameterName); + assertNull(rval); + + validatorTester.verify(testParameterValue, PARAMETER_STRING_CANONCALIZE_TYPE_KEY, SECURITY_CONFIGURATION_TEST_LENGTH, true); + + verify(mockSecConfig, times(1)).getIntProp(SECURITY_CONFIGURATION_PARAMETER_STRING_LENGTH_KEY_NAME); + verify(mockRequest, times(1)).getParameter(testParameterName); + } + + @Test + public void testGetParameterStringBooleanNullEvalPassthrough() throws Exception{ + ValidatorTestContainer validatorTester = new ValidatorTestContainer(mockValidator); + validatorTester.getValidInputReturns(null); + + PowerMockito.when(mockSecConfig.getIntProp(SECURITY_CONFIGURATION_PARAMETER_STRING_LENGTH_KEY_NAME)).thenReturn( + SECURITY_CONFIGURATION_TEST_LENGTH); + + PowerMockito.when(mockRequest.getParameter(testParameterName)).thenReturn(testParameterValue); + + SecurityWrapperRequest request = new SecurityWrapperRequest(mockRequest); + String rval = request.getParameter(testParameterName, false); + assertNull(rval); + + validatorTester.verify(testParameterValue, PARAMETER_STRING_CANONCALIZE_TYPE_KEY, SECURITY_CONFIGURATION_TEST_LENGTH, false); + + verify(mockSecConfig, times(1)).getIntProp(SECURITY_CONFIGURATION_PARAMETER_STRING_LENGTH_KEY_NAME); + verify(mockRequest, times(1)).getParameter(testParameterName); + } + + @Test + public void testGetParameterStringBooleanIntNullEvalPassthrough() throws Exception{ + ValidatorTestContainer validatorTester = new ValidatorTestContainer(mockValidator); + validatorTester.getValidInputReturns(null); + + PowerMockito.when(mockRequest.getParameter(testParameterName)).thenReturn(testParameterValue); + + SecurityWrapperRequest request = new SecurityWrapperRequest(mockRequest); + String rval = request.getParameter(testParameterName, false, testMaximumLength); + assertNull(rval); + + validatorTester.verify(testParameterValue, PARAMETER_STRING_CANONCALIZE_TYPE_KEY, testMaximumLength, false); + + verify(mockRequest, times(1)).getParameter(testParameterName); + } + + @Test + public void testGetParameterStringBooleanIntStringNullEvalPassthrough() throws Exception{ + ValidatorTestContainer validatorTester = new ValidatorTestContainer(mockValidator); + validatorTester.getValidInputReturns(null); + + PowerMockito.when(mockRequest.getParameter(testParameterName)).thenReturn(testParameterValue); + + SecurityWrapperRequest request = new SecurityWrapperRequest(mockRequest); + String rval = request.getParameter(testParameterName, false, testMaximumLength, testValidatorType); + assertNull(rval); + validatorTester.verify(testParameterValue, testValidatorType, testMaximumLength, false); + + verify(mockRequest, times(1)).getParameter(testParameterName); + } + + @Test + public void testGetParameterStringNullOnException() throws Exception{ + ValidatorTestContainer validatorTester = new ValidatorTestContainer(mockValidator); + validatorTester.getValidInputThrows(); + + PowerMockito.when(mockSecConfig.getIntProp(SECURITY_CONFIGURATION_PARAMETER_STRING_LENGTH_KEY_NAME)).thenReturn( + SECURITY_CONFIGURATION_TEST_LENGTH); + + PowerMockito.when(mockRequest.getParameter(testParameterName)).thenReturn(testParameterValue); + + SecurityWrapperRequest request = new SecurityWrapperRequest(mockRequest); + String rval = request.getParameter(testParameterName); + assertNull(rval); + + validatorTester.verify(testParameterValue, PARAMETER_STRING_CANONCALIZE_TYPE_KEY, SECURITY_CONFIGURATION_TEST_LENGTH, true); + + verify(mockSecConfig, times(1)).getIntProp(SECURITY_CONFIGURATION_PARAMETER_STRING_LENGTH_KEY_NAME); + verify(mockRequest, times(1)).getParameter(testParameterName); + } + + + + @Test + public void testGetParameterStringBooleanNullOnException() throws Exception{ + ValidatorTestContainer validatorTester = new ValidatorTestContainer(mockValidator); + validatorTester.getValidInputThrows(); + + PowerMockito.when(mockSecConfig.getIntProp(SECURITY_CONFIGURATION_PARAMETER_STRING_LENGTH_KEY_NAME)).thenReturn( + SECURITY_CONFIGURATION_TEST_LENGTH); + + PowerMockito.when(mockRequest.getParameter(testParameterName)).thenReturn(testParameterValue); + + SecurityWrapperRequest request = new SecurityWrapperRequest(mockRequest); + String rval = request.getParameter(testParameterName, false); + assertNull(rval); + + validatorTester.verify(testParameterValue, PARAMETER_STRING_CANONCALIZE_TYPE_KEY, SECURITY_CONFIGURATION_TEST_LENGTH, false); + + verify(mockSecConfig, times(1)).getIntProp(SECURITY_CONFIGURATION_PARAMETER_STRING_LENGTH_KEY_NAME); + verify(mockRequest, times(1)).getParameter(testParameterName); + } + + @Test + public void testGetParameterStringBooleanIntNullOnException() throws Exception{ + ValidatorTestContainer validatorTester = new ValidatorTestContainer(mockValidator); + validatorTester.getValidInputThrows(); + + PowerMockito.when(mockRequest.getParameter(testParameterName)).thenReturn(testParameterValue); + + SecurityWrapperRequest request = new SecurityWrapperRequest(mockRequest); + String rval = request.getParameter(testParameterName, false, testMaximumLength); + assertNull(rval); + + validatorTester.verify(testParameterValue, PARAMETER_STRING_CANONCALIZE_TYPE_KEY, testMaximumLength, false); + verify(mockRequest, times(1)).getParameter(testParameterName); + } + + @Test + public void testGetParameterStringBooleanIntStringNullOnException() throws Exception{ + ValidatorTestContainer validatorTester = new ValidatorTestContainer(mockValidator); + validatorTester.getValidInputThrows(); + + PowerMockito.when(mockRequest.getParameter(testParameterName)).thenReturn(testParameterValue); + + SecurityWrapperRequest request = new SecurityWrapperRequest(mockRequest); + String rval = request.getParameter(testParameterName, false, testMaximumLength, testValidatorType); + assertNull(rval); + + validatorTester.verify(testParameterValue, testValidatorType, testMaximumLength, false); + + verify(mockRequest, times(1)).getParameter(testParameterName); + } + + @Test + public void testGetCookie() throws Exception { + PowerMockito.when(mockSecConfig.getIntProp(SECURITY_CONFIGURATION_HEADER_NAME_LENGTH_KEY_NAME)).thenReturn( + SECURITY_CONFIGURATION_TEST_LENGTH); + PowerMockito.when(mockSecConfig.getIntProp(SECURITY_CONFIGURATION_HEADER_VALUE_LENGTH_KEY_NAME)).thenReturn( + SECURITY_CONFIGURATION_TEST_LENGTH); + + Cookie ck1 = new Cookie(testName.getMethodName(), testName.getMethodName()+ "-VALUE"); + ck1.setMaxAge(999); + ck1.setDomain(testName.getMethodName() + "-DOMAIN"); + ck1.setPath(testName.getMethodName() + "-URI"); + + Cookie[] stubCookies = new Cookie[] {ck1}; + PowerMockito.when(mockRequest.getCookies()).thenReturn(stubCookies); + + PowerMockito.when(mockValidator.getValidInput(anyString(), eq(ck1.getName()), eq(COOKIE_NAME_TYPE_KEY), eq(SECURITY_CONFIGURATION_TEST_LENGTH), eq(false))).thenReturn(ck1.getName()); + PowerMockito.when(mockValidator.getValidInput(anyString(), eq(ck1.getValue()),eq(COOKIE_VALUE_TYPE_KEY), eq(SECURITY_CONFIGURATION_TEST_LENGTH), eq(true))).thenReturn(ck1.getValue()); + PowerMockito.when(mockValidator.getValidInput(anyString(), eq(ck1.getDomain()),eq(COOKIE_DOMAIN_TYPE_KEY), eq(SECURITY_CONFIGURATION_TEST_LENGTH), eq(false))).thenReturn(ck1.getDomain()); + PowerMockito.when(mockValidator.getValidInput(anyString(), eq(ck1.getPath()), eq(COOKIE_PATH_TYPE_KEY), eq(SECURITY_CONFIGURATION_TEST_LENGTH), eq(false))).thenReturn(ck1.getPath()); + + SecurityWrapperRequest request = new SecurityWrapperRequest(mockRequest); + Cookie[] cookies = request.getCookies(); + assertNotEquals(stubCookies, cookies); + assertEquals(1, cookies.length); + Cookie resultCookie = cookies[0]; + assertNotEquals(ck1, resultCookie); + assertEquals(ck1.getName(), resultCookie.getName()); + assertEquals(ck1.getValue(), resultCookie.getValue()); + assertEquals(ck1.getDomain(), resultCookie.getDomain()); + assertEquals(ck1.getPath(), resultCookie.getPath()); + assertEquals(ck1.getMaxAge(), resultCookie.getMaxAge()); + + Mockito.verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(ck1.getName()), ArgumentMatchers.eq(COOKIE_NAME_TYPE_KEY), ArgumentMatchers.eq(SECURITY_CONFIGURATION_TEST_LENGTH), ArgumentMatchers.eq(false)); + Mockito.verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(ck1.getValue()), ArgumentMatchers.eq(COOKIE_VALUE_TYPE_KEY), ArgumentMatchers.eq(SECURITY_CONFIGURATION_TEST_LENGTH), ArgumentMatchers.eq(true)); + Mockito.verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(ck1.getDomain()), ArgumentMatchers.eq(COOKIE_DOMAIN_TYPE_KEY), ArgumentMatchers.eq(SECURITY_CONFIGURATION_TEST_LENGTH), ArgumentMatchers.eq(false)); + Mockito.verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(ck1.getPath()), ArgumentMatchers.eq(COOKIE_PATH_TYPE_KEY), ArgumentMatchers.eq(SECURITY_CONFIGURATION_TEST_LENGTH), ArgumentMatchers.eq(false)); + } + + @Test + public void testGetCookieNullDomainPath() throws Exception { + PowerMockito.when(mockSecConfig.getIntProp(SECURITY_CONFIGURATION_HEADER_NAME_LENGTH_KEY_NAME)).thenReturn( + SECURITY_CONFIGURATION_TEST_LENGTH); + PowerMockito.when(mockSecConfig.getIntProp(SECURITY_CONFIGURATION_HEADER_VALUE_LENGTH_KEY_NAME)).thenReturn( + SECURITY_CONFIGURATION_TEST_LENGTH); + + Cookie ck1 = new Cookie(testName.getMethodName(), testName.getMethodName()+ "-VALUE"); + ck1.setMaxAge(999); + //Domain and Path are left null + + Cookie[] stubCookies = new Cookie[] {ck1}; + PowerMockito.when(mockRequest.getCookies()).thenReturn(stubCookies); + + PowerMockito.when(mockValidator.getValidInput(anyString(), eq(ck1.getName()), eq(COOKIE_NAME_TYPE_KEY), eq(SECURITY_CONFIGURATION_TEST_LENGTH), eq(false))).thenReturn(ck1.getName()); + PowerMockito.when(mockValidator.getValidInput(anyString(), eq(ck1.getValue()),eq(COOKIE_VALUE_TYPE_KEY), eq(SECURITY_CONFIGURATION_TEST_LENGTH), eq(true))).thenReturn(ck1.getValue()); + + SecurityWrapperRequest request = new SecurityWrapperRequest(mockRequest); + Cookie[] cookies = request.getCookies(); + assertNotEquals(stubCookies, cookies); + assertEquals(1, cookies.length); + Cookie resultCookie1 = cookies[0]; + + assertNotEquals(ck1, resultCookie1); + assertEquals(ck1.getName(), resultCookie1.getName()); + assertEquals(ck1.getValue(), resultCookie1.getValue()); + assertEquals(ck1.getDomain(), resultCookie1.getDomain()); + assertEquals(ck1.getPath(), resultCookie1.getPath()); + assertEquals(ck1.getMaxAge(), resultCookie1.getMaxAge()); + + Mockito.verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(ck1.getName()), ArgumentMatchers.eq(COOKIE_NAME_TYPE_KEY), ArgumentMatchers.eq(SECURITY_CONFIGURATION_TEST_LENGTH), ArgumentMatchers.eq(false)); + Mockito.verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(ck1.getValue()), ArgumentMatchers.eq(COOKIE_VALUE_TYPE_KEY), ArgumentMatchers.eq(SECURITY_CONFIGURATION_TEST_LENGTH), ArgumentMatchers.eq(true)); + Mockito.verify(mockValidator, times(0)).getValidInput(anyString(), ArgumentMatchers.eq(ck1.getDomain()), ArgumentMatchers.eq(COOKIE_DOMAIN_TYPE_KEY), ArgumentMatchers.eq(SECURITY_CONFIGURATION_TEST_LENGTH), ArgumentMatchers.eq(false)); + Mockito.verify(mockValidator, times(0)).getValidInput(anyString(), ArgumentMatchers.eq(ck1.getPath()), ArgumentMatchers.eq(COOKIE_PATH_TYPE_KEY), ArgumentMatchers.eq(SECURITY_CONFIGURATION_TEST_LENGTH), ArgumentMatchers.eq(false)); + } + + @Test + public void testGetCookieNullRequestCookies() { + PowerMockito.when(mockRequest.getParameter(testParameterName)).thenReturn(testParameterValue); + PowerMockito.when(mockRequest.getCookies()).thenReturn(null); + SecurityWrapperRequest request = new SecurityWrapperRequest(mockRequest); + Cookie[] cookies = request.getCookies(); + assertEquals(0, cookies.length); + } + + @Test + public void testGetCookieSkipOnBadName() throws Exception { + PowerMockito.when(mockSecConfig.getIntProp(SECURITY_CONFIGURATION_HEADER_NAME_LENGTH_KEY_NAME)).thenReturn( + SECURITY_CONFIGURATION_TEST_LENGTH); + PowerMockito.when(mockSecConfig.getIntProp(SECURITY_CONFIGURATION_HEADER_VALUE_LENGTH_KEY_NAME)).thenReturn( + SECURITY_CONFIGURATION_TEST_LENGTH); + + Answer exceptionAnswer = new ValidatorTestContainer(mockValidator).throwException(); + + Cookie ck1 = new Cookie(testName.getMethodName(), testName.getMethodName()+ "-VALUE"); + ck1.setMaxAge(999); + ck1.setDomain(testName.getMethodName() + "-DOMAIN"); + ck1.setPath(testName.getMethodName() + "-URI"); + + Cookie[] stubCookies = new Cookie[] {ck1}; + PowerMockito.when(mockRequest.getCookies()).thenReturn(stubCookies); + + PowerMockito.when(mockValidator.getValidInput(anyString(), eq(ck1.getName()), eq(COOKIE_NAME_TYPE_KEY), eq(SECURITY_CONFIGURATION_TEST_LENGTH), eq(false))).thenAnswer(exceptionAnswer); + + SecurityWrapperRequest request = new SecurityWrapperRequest(mockRequest); + Cookie[] cookies = request.getCookies(); + assertNotEquals(stubCookies, cookies); + assertEquals(0, cookies.length); + + Mockito.verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(ck1.getName()), ArgumentMatchers.eq(COOKIE_NAME_TYPE_KEY), ArgumentMatchers.eq(SECURITY_CONFIGURATION_TEST_LENGTH), ArgumentMatchers.eq(false)); + Mockito.verify(mockValidator, times(0)).getValidInput(anyString(), ArgumentMatchers.eq(ck1.getValue()), ArgumentMatchers.eq(COOKIE_VALUE_TYPE_KEY), ArgumentMatchers.eq(SECURITY_CONFIGURATION_TEST_LENGTH), ArgumentMatchers.eq(true)); + Mockito.verify(mockValidator, times(0)).getValidInput(anyString(), ArgumentMatchers.eq(ck1.getDomain()), ArgumentMatchers.eq(COOKIE_DOMAIN_TYPE_KEY), ArgumentMatchers.eq(SECURITY_CONFIGURATION_TEST_LENGTH), ArgumentMatchers.eq(false)); + Mockito.verify(mockValidator, times(0)).getValidInput(anyString(), ArgumentMatchers.eq(ck1.getPath()), ArgumentMatchers.eq(COOKIE_PATH_TYPE_KEY), ArgumentMatchers.eq(SECURITY_CONFIGURATION_TEST_LENGTH), ArgumentMatchers.eq(false)); + + //I would have liked to verify the logging occurred, but it's giving me trouble at this time. + } + + @Test + public void testGetCookieSkipOnBadValue() throws Exception { + PowerMockito.when(mockSecConfig.getIntProp(SECURITY_CONFIGURATION_HEADER_NAME_LENGTH_KEY_NAME)).thenReturn( + SECURITY_CONFIGURATION_TEST_LENGTH); + PowerMockito.when(mockSecConfig.getIntProp(SECURITY_CONFIGURATION_HEADER_VALUE_LENGTH_KEY_NAME)).thenReturn( + SECURITY_CONFIGURATION_TEST_LENGTH); + + Answer exceptionAnswer = new ValidatorTestContainer(mockValidator).throwException(); + + Cookie ck1 = new Cookie(testName.getMethodName(), testName.getMethodName()+ "-VALUE"); + ck1.setMaxAge(999); + ck1.setDomain(testName.getMethodName() + "-DOMAIN"); + ck1.setPath(testName.getMethodName() + "-URI"); + + Cookie[] stubCookies = new Cookie[] {ck1}; + PowerMockito.when(mockRequest.getCookies()).thenReturn(stubCookies); + + PowerMockito.when(mockValidator.getValidInput(anyString(), eq(ck1.getName()), eq(COOKIE_NAME_TYPE_KEY), eq(SECURITY_CONFIGURATION_TEST_LENGTH), eq(true))).thenReturn(ck1.getName()); + PowerMockito.when(mockValidator.getValidInput(anyString(), eq(ck1.getValue()),eq(COOKIE_VALUE_TYPE_KEY), eq(SECURITY_CONFIGURATION_TEST_LENGTH), eq(true))).thenAnswer(exceptionAnswer); + + SecurityWrapperRequest request = new SecurityWrapperRequest(mockRequest); + Cookie[] cookies = request.getCookies(); + assertNotEquals(stubCookies, cookies); + assertEquals(0, cookies.length); + + Mockito.verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(ck1.getName()), ArgumentMatchers.eq(COOKIE_NAME_TYPE_KEY), ArgumentMatchers.eq(SECURITY_CONFIGURATION_TEST_LENGTH), ArgumentMatchers.eq(false)); + Mockito.verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(ck1.getValue()), ArgumentMatchers.eq(COOKIE_VALUE_TYPE_KEY), ArgumentMatchers.eq(SECURITY_CONFIGURATION_TEST_LENGTH), ArgumentMatchers.eq(true)); + Mockito.verify(mockValidator, times(0)).getValidInput(anyString(), ArgumentMatchers.eq(ck1.getDomain()), ArgumentMatchers.eq(COOKIE_DOMAIN_TYPE_KEY), ArgumentMatchers.eq(SECURITY_CONFIGURATION_TEST_LENGTH), ArgumentMatchers.eq(false)); + Mockito.verify(mockValidator, times(0)).getValidInput(anyString(), ArgumentMatchers.eq(ck1.getPath()), ArgumentMatchers.eq(COOKIE_PATH_TYPE_KEY), ArgumentMatchers.eq(SECURITY_CONFIGURATION_TEST_LENGTH), ArgumentMatchers.eq(false)); + + //I would have liked to verify the logging occurred, but it's giving me trouble at this time. + } + + @Test + public void testGetCookieSkipOnBadDomain() throws Exception { + PowerMockito.when(mockSecConfig.getIntProp(SECURITY_CONFIGURATION_HEADER_NAME_LENGTH_KEY_NAME)).thenReturn( + SECURITY_CONFIGURATION_TEST_LENGTH); + PowerMockito.when(mockSecConfig.getIntProp(SECURITY_CONFIGURATION_HEADER_VALUE_LENGTH_KEY_NAME)).thenReturn( + SECURITY_CONFIGURATION_TEST_LENGTH); + + Answer exceptionAnswer = new ValidatorTestContainer(mockValidator).throwException(); + + Cookie ck1 = new Cookie(testName.getMethodName(), testName.getMethodName()+ "-VALUE"); + ck1.setMaxAge(999); + ck1.setDomain(testName.getMethodName() + "-DOMAIN"); + ck1.setPath(testName.getMethodName() + "-URI"); + + Cookie[] stubCookies = new Cookie[] {ck1}; + PowerMockito.when(mockRequest.getCookies()).thenReturn(stubCookies); + + PowerMockito.when(mockValidator.getValidInput(anyString(), eq(ck1.getName()), eq(COOKIE_NAME_TYPE_KEY), eq(SECURITY_CONFIGURATION_TEST_LENGTH), eq(false))).thenReturn(ck1.getName()); + PowerMockito.when(mockValidator.getValidInput(anyString(), eq(ck1.getValue()),eq(COOKIE_VALUE_TYPE_KEY), eq(SECURITY_CONFIGURATION_TEST_LENGTH), eq(true))).thenReturn(ck1.getValue()); + PowerMockito.when(mockValidator.getValidInput(anyString(), eq(ck1.getDomain()),eq(COOKIE_DOMAIN_TYPE_KEY), eq(SECURITY_CONFIGURATION_TEST_LENGTH), eq(false))).thenAnswer(exceptionAnswer); + + SecurityWrapperRequest request = new SecurityWrapperRequest(mockRequest); + Cookie[] cookies = request.getCookies(); + assertNotEquals(stubCookies, cookies); + assertEquals(0, cookies.length); + + Mockito.verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(ck1.getName()), ArgumentMatchers.eq(COOKIE_NAME_TYPE_KEY), ArgumentMatchers.eq(SECURITY_CONFIGURATION_TEST_LENGTH), ArgumentMatchers.eq(false)); + Mockito.verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(ck1.getValue()), ArgumentMatchers.eq(COOKIE_VALUE_TYPE_KEY), ArgumentMatchers.eq(SECURITY_CONFIGURATION_TEST_LENGTH), ArgumentMatchers.eq(true)); + Mockito.verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(ck1.getDomain()), ArgumentMatchers.eq(COOKIE_DOMAIN_TYPE_KEY), ArgumentMatchers.eq(SECURITY_CONFIGURATION_TEST_LENGTH), ArgumentMatchers.eq(false)); + Mockito.verify(mockValidator, times(0)).getValidInput(anyString(), ArgumentMatchers.eq(ck1.getPath()), ArgumentMatchers.eq(COOKIE_PATH_TYPE_KEY), ArgumentMatchers.eq(SECURITY_CONFIGURATION_TEST_LENGTH), ArgumentMatchers.eq(false)); + + //I would have liked to verify the logging occurred, but it's giving me trouble at this time. + } + + + @Test + public void testGetCookieSkipOnBadPath() throws Exception { + PowerMockito.when(mockSecConfig.getIntProp(SECURITY_CONFIGURATION_HEADER_NAME_LENGTH_KEY_NAME)).thenReturn( + SECURITY_CONFIGURATION_TEST_LENGTH); + PowerMockito.when(mockSecConfig.getIntProp(SECURITY_CONFIGURATION_HEADER_VALUE_LENGTH_KEY_NAME)).thenReturn( + SECURITY_CONFIGURATION_TEST_LENGTH); + + Answer exceptionAnswer = new ValidatorTestContainer(mockValidator).throwException(); + + Cookie ck1 = new Cookie(testName.getMethodName(), testName.getMethodName()+ "-VALUE"); + ck1.setMaxAge(999); + ck1.setDomain(testName.getMethodName() + "-DOMAIN"); + ck1.setPath(testName.getMethodName() + "-URI"); + + Cookie[] stubCookies = new Cookie[] {ck1}; + PowerMockito.when(mockRequest.getCookies()).thenReturn(stubCookies); + + PowerMockito.when(mockValidator.getValidInput(anyString(), eq(ck1.getName()), eq(COOKIE_NAME_TYPE_KEY), eq(SECURITY_CONFIGURATION_TEST_LENGTH), eq(false))).thenReturn(ck1.getName()); + PowerMockito.when(mockValidator.getValidInput(anyString(), eq(ck1.getValue()),eq(COOKIE_VALUE_TYPE_KEY), eq(SECURITY_CONFIGURATION_TEST_LENGTH), eq(true))).thenReturn(ck1.getValue()); + PowerMockito.when(mockValidator.getValidInput(anyString(), eq(ck1.getDomain()),eq(COOKIE_DOMAIN_TYPE_KEY), eq(SECURITY_CONFIGURATION_TEST_LENGTH), eq(false))).thenReturn(ck1.getDomain()); + PowerMockito.when(mockValidator.getValidInput(anyString(), eq(ck1.getPath()), eq(COOKIE_PATH_TYPE_KEY), eq(SECURITY_CONFIGURATION_TEST_LENGTH), eq(false))).thenAnswer(exceptionAnswer); + + SecurityWrapperRequest request = new SecurityWrapperRequest(mockRequest); + Cookie[] cookies = request.getCookies(); + assertNotEquals(stubCookies, cookies); + assertEquals(0, cookies.length); + + Mockito.verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(ck1.getName()), ArgumentMatchers.eq(COOKIE_NAME_TYPE_KEY), ArgumentMatchers.eq(SECURITY_CONFIGURATION_TEST_LENGTH), ArgumentMatchers.eq(false)); + Mockito.verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(ck1.getValue()), ArgumentMatchers.eq(COOKIE_VALUE_TYPE_KEY), ArgumentMatchers.eq(SECURITY_CONFIGURATION_TEST_LENGTH), ArgumentMatchers.eq(true)); + Mockito.verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(ck1.getDomain()), ArgumentMatchers.eq(COOKIE_DOMAIN_TYPE_KEY), ArgumentMatchers.eq(SECURITY_CONFIGURATION_TEST_LENGTH), ArgumentMatchers.eq(false)); + Mockito.verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(ck1.getPath()), ArgumentMatchers.eq(COOKIE_PATH_TYPE_KEY), ArgumentMatchers.eq(SECURITY_CONFIGURATION_TEST_LENGTH), ArgumentMatchers.eq(false)); + + //I would have liked to verify the logging occurred, but it's giving me trouble at this time. + } + + /** + * Utility test class meant to encapsulate common interactions for preparing and + * verifying the Validator interactions common to multiple tests. + * + */ + private class ValidatorTestContainer { + private ArgumentCaptor inputCapture = ArgumentCaptor.forClass(String.class); + private ArgumentCaptor typeCapture = ArgumentCaptor.forClass(String.class); + private ArgumentCaptor lengthCapture = ArgumentCaptor.forClass(Integer.class); + private ArgumentCaptor allowNullCapture = ArgumentCaptor.forClass(Boolean.class); + private Validator validator; + + + public ValidatorTestContainer(Validator validatorRef) { + this.validator = validatorRef; + } + public Answer throwException() { + return new Answer() { + @Override + public String answer(InvocationOnMock invocation) throws Throwable { + throw new ValidationException("Thrown from test Scope", "Test Exception is intentional."); + } + }; + } + + public Answer returnResult(final String result) { + return new Answer() { + @Override + public String answer(InvocationOnMock invocation) throws Throwable { + return result; + } + }; + } + public void getValidInputReturns(String response) throws Exception { + setupFor(returnResult(response)); + } + + public void getValidInputThrows() throws Exception { + setupFor(throwException()); + } + + public void setupFor(Answer answer) throws Exception { + String context = anyString(); + String input = inputCapture.capture(); + String type = typeCapture.capture(); + Integer length = lengthCapture.capture(); + Boolean allowNull = allowNullCapture.capture(); + + PowerMockito.when(validator.getValidInput(context, input, type, length, allowNull)).thenAnswer(answer); + } + + public void verify(String input, String type, int maxLen, boolean allowNull) throws Exception { + String actualInput = inputCapture.getValue(); + String actualType = typeCapture.getValue(); + int actualLength = lengthCapture.getValue().intValue(); + boolean actualAllowNull = allowNullCapture.getValue().booleanValue(); + + assertEquals(input, actualInput); + assertEquals(type, actualType); + assertTrue(maxLen == actualLength); + assertEquals(allowNull, actualAllowNull); + + Mockito.verify(validator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(input), ArgumentMatchers.eq(type), ArgumentMatchers.eq(maxLen), ArgumentMatchers.eq(allowNull)); + } + } +} diff --git a/src/test/java/org/owasp/esapi/filters/SecurityWrapperResponseTest.java b/src/test/java/org/owasp/esapi/filters/SecurityWrapperResponseTest.java new file mode 100644 index 000000000..f7b74c6f1 --- /dev/null +++ b/src/test/java/org/owasp/esapi/filters/SecurityWrapperResponseTest.java @@ -0,0 +1,809 @@ +package org.owasp.esapi.filters; + +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.owasp.esapi.PropNames.DISABLE_INTRUSION_DETECTION; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletResponse; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestName; +import org.junit.runner.RunWith; +import org.mockito.ArgumentMatchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Logger; +import org.owasp.esapi.SecurityConfiguration; +import org.owasp.esapi.Validator; +import org.owasp.esapi.errors.ValidationException; +import org.owasp.esapi.http.MockHttpServletResponse; +import org.owasp.esapi.util.TestUtils; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +//@PrepareForTest({SecurityWrapperResponse.class}) +@RunWith(PowerMockRunner.class) +@PrepareForTest(ESAPI.class) +@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "org.w3c.dom.*"}) +public class SecurityWrapperResponseTest { + private static final String HEADER_NAME_CONTEXT = "HTTPHeaderName"; + private static final String HEADER_VALUE_CONTEXT = "HTTPHeaderValue"; + private static final String SEC_CTX_MAX_HEADER_NAME_SIZE_ATTR = "HttpUtilities.MaxHeaderNameSize"; + private static final String SEC_CTX_MAX_HEADER_VALUE_SIZE_ATTR = "HttpUtilities.MaxHeaderValueSize"; + + + @Rule + public TestName testName = new TestName(); + + @Mock + private HttpServletResponse mockResponse; + @Mock + private Validator mockValidator; + @Mock + private SecurityConfiguration mockSecConfig; + @Mock + private Logger mockLogger; + + private String goodHeaderName; + private String goodHeaderValue; + + @Before + public void setup() throws Exception { + //preconfig will impact other tests unless isolated. Still don't want to duplicate it though. + if (testName.getMethodName().startsWith("testSetHeader") || + testName.getMethodName().startsWith("testAddHeader")) { + PowerMockito.mockStatic(ESAPI.class); + PowerMockito.when(ESAPI.class, SecurityWrapperRequestTest.ESAPI_VALIDATOR_GETTER_METHOD_NAME).thenReturn(mockValidator); + PowerMockito.when(ESAPI.class, SecurityWrapperRequestTest.ESAPI_GET_LOGGER_METHOD_NAME, "SecurityWrapperResponse").thenReturn(mockLogger); + PowerMockito.when(ESAPI.class, SecurityWrapperRequestTest.ESAPY_SECURITY_CONFIGURATION_GETTER_METHOD_NAME).thenReturn(mockSecConfig); + //Is intrusion detection disabled? A: Yes, it is off. + //This logic is confusing: True, the value is False... + Mockito.when( mockSecConfig.getBooleanProp( DISABLE_INTRUSION_DETECTION ) ).thenReturn(true); + + goodHeaderName = testName.getMethodName() + "_goodHeaderName"; + goodHeaderValue = testName.getMethodName() + "_goodHeaderValue"; + } + } + + @Test + public void testSetHeaderHappyPath() throws Exception { + String validateNameResponse = goodHeaderName; + String validateValueResponse = goodHeaderValue; + PowerMockito.when(mockValidator.getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderName), + ArgumentMatchers.eq(HEADER_NAME_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false))).thenReturn(validateNameResponse); + + PowerMockito.when(mockValidator.getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderValue), + ArgumentMatchers.eq(HEADER_VALUE_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false))).thenReturn(validateValueResponse); + + PowerMockito.when(mockSecConfig.getIntProp(SEC_CTX_MAX_HEADER_NAME_SIZE_ATTR)).thenReturn( + SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH); + + PowerMockito.when(mockSecConfig.getIntProp(SEC_CTX_MAX_HEADER_VALUE_SIZE_ATTR)).thenReturn( + SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH); + + SecurityWrapperResponse response = new SecurityWrapperResponse(mockResponse); + + response.setHeader(goodHeaderName, goodHeaderValue); + + verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderName), ArgumentMatchers.eq(HEADER_NAME_CONTEXT), ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), ArgumentMatchers.eq(false)); + verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderValue), ArgumentMatchers.eq(HEADER_VALUE_CONTEXT), ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), ArgumentMatchers.eq(false)); + verify(mockSecConfig, times(1)).getIntProp(SEC_CTX_MAX_HEADER_NAME_SIZE_ATTR); + verify(mockSecConfig, times(1)).getIntProp(SEC_CTX_MAX_HEADER_VALUE_SIZE_ATTR); + verify(mockResponse, times(1)).setHeader(validateNameResponse, validateValueResponse); + verify(mockLogger,times(0)).warning(ArgumentMatchers.any(org.owasp.esapi.Logger.EventType.class), anyString(), ArgumentMatchers.any(Exception.class)); + } + + @Test + public void testSetHeaderNameNull() throws Exception { + String validateNameResponse = null; + String validateValueResponse = goodHeaderValue; + PowerMockito.when(mockValidator.getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderName), + ArgumentMatchers.eq(HEADER_NAME_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false))).thenReturn(validateNameResponse); + + PowerMockito.when(mockValidator.getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderValue), + ArgumentMatchers.eq(HEADER_VALUE_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false))).thenReturn(validateValueResponse); + + PowerMockito.when(mockSecConfig.getIntProp(SEC_CTX_MAX_HEADER_NAME_SIZE_ATTR)).thenReturn( + SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH); + + PowerMockito.when(mockSecConfig.getIntProp(SEC_CTX_MAX_HEADER_VALUE_SIZE_ATTR)).thenReturn( + SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH); + + SecurityWrapperResponse response = new SecurityWrapperResponse(mockResponse); + + response.setHeader(goodHeaderName, goodHeaderValue); + + verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderName), + ArgumentMatchers.eq(HEADER_NAME_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false)); + verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderValue), + ArgumentMatchers.eq(HEADER_VALUE_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false)); + verify(mockSecConfig, times(1)).getIntProp(SEC_CTX_MAX_HEADER_NAME_SIZE_ATTR); + verify(mockSecConfig, times(1)).getIntProp(SEC_CTX_MAX_HEADER_VALUE_SIZE_ATTR); + verify(mockResponse, times(0)).setHeader(anyString(), anyString()); + verify(mockLogger, times(0)).warning(ArgumentMatchers.any(org.owasp.esapi.Logger.EventType.class),anyString(), + ArgumentMatchers.any(Exception.class)); + } + + @Test + public void testSetHeaderNameEmpty() throws Exception { + String validateNameResponse = " "; + String validateValueResponse = goodHeaderValue; + PowerMockito.when(mockValidator.getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderName), + ArgumentMatchers.eq(HEADER_NAME_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false))).thenReturn(validateNameResponse); + + PowerMockito.when(mockValidator.getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderValue), + ArgumentMatchers.eq(HEADER_VALUE_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false))).thenReturn(validateValueResponse); + + PowerMockito.when(mockSecConfig.getIntProp(SEC_CTX_MAX_HEADER_NAME_SIZE_ATTR)).thenReturn( + SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH); + + PowerMockito.when(mockSecConfig.getIntProp(SEC_CTX_MAX_HEADER_VALUE_SIZE_ATTR)).thenReturn( + SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH); + + SecurityWrapperResponse response = new SecurityWrapperResponse(mockResponse); + + response.setHeader(goodHeaderName, goodHeaderValue); + + verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderName), + ArgumentMatchers.eq(HEADER_NAME_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false)); + verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderValue), + ArgumentMatchers.eq(HEADER_VALUE_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false)); + verify(mockSecConfig, times(1)).getIntProp(SEC_CTX_MAX_HEADER_NAME_SIZE_ATTR); + verify(mockSecConfig, times(1)).getIntProp(SEC_CTX_MAX_HEADER_VALUE_SIZE_ATTR); + verify(mockResponse, times(0)).setHeader(anyString(), anyString()); + verify(mockLogger, times(0)).warning(ArgumentMatchers.any(org.owasp.esapi.Logger.EventType.class),anyString(), + ArgumentMatchers.any(Exception.class)); + } + + @Test + public void testSetHeaderNameThrowsValidationException() throws Exception { + String validateValueResponse = goodHeaderValue; + PowerMockito.when(mockValidator.getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderName), + ArgumentMatchers.eq(HEADER_NAME_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false))).thenThrow(ValidationException.class); + + PowerMockito.when(mockValidator.getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderValue), + ArgumentMatchers.eq(HEADER_VALUE_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false))).thenReturn(validateValueResponse); + + PowerMockito.when(mockSecConfig.getIntProp(SEC_CTX_MAX_HEADER_NAME_SIZE_ATTR)).thenReturn( + SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH); + + PowerMockito.when(mockSecConfig.getIntProp(SEC_CTX_MAX_HEADER_VALUE_SIZE_ATTR)).thenReturn( + SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH); + + SecurityWrapperResponse response = new SecurityWrapperResponse(mockResponse); + + response.setHeader(goodHeaderName, goodHeaderValue); + + verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderName), + ArgumentMatchers.eq(HEADER_NAME_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false)); + verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderValue), + ArgumentMatchers.eq(HEADER_VALUE_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false)); + verify(mockSecConfig, times(1)).getIntProp(SEC_CTX_MAX_HEADER_NAME_SIZE_ATTR); + verify(mockSecConfig, times(1)).getIntProp(SEC_CTX_MAX_HEADER_VALUE_SIZE_ATTR); + verify(mockResponse, times(0)).setHeader(anyString(), anyString()); + + verify(mockLogger, times(1)).warning(ArgumentMatchers.any(org.owasp.esapi.Logger.EventType.class), + ArgumentMatchers.contains("Attempt to set invalid header NAME denied: HTTPHeaderName:"+ goodHeaderName), + ArgumentMatchers.any(Exception.class)); + } + + @Test + public void testSetHeaderValueNull() throws Exception { + String validateNameResponse = goodHeaderName; + String validateValueResponse = null; + PowerMockito.when(mockValidator.getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderName), + ArgumentMatchers.eq(HEADER_NAME_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false))).thenReturn(validateNameResponse); + + PowerMockito.when(mockValidator.getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderValue), + ArgumentMatchers.eq(HEADER_VALUE_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false))).thenReturn(validateValueResponse); + + PowerMockito.when(mockSecConfig.getIntProp(SEC_CTX_MAX_HEADER_NAME_SIZE_ATTR)).thenReturn( + SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH); + + PowerMockito.when(mockSecConfig.getIntProp(SEC_CTX_MAX_HEADER_VALUE_SIZE_ATTR)).thenReturn( + SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH); + + SecurityWrapperResponse response = new SecurityWrapperResponse(mockResponse); + + response.setHeader(goodHeaderName, goodHeaderValue); + + verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderName), + ArgumentMatchers.eq(HEADER_NAME_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false)); + verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderValue), + ArgumentMatchers.eq(HEADER_VALUE_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false)); + verify(mockSecConfig, times(1)).getIntProp(SEC_CTX_MAX_HEADER_NAME_SIZE_ATTR); + verify(mockSecConfig, times(1)).getIntProp(SEC_CTX_MAX_HEADER_VALUE_SIZE_ATTR); + verify(mockResponse, times(0)).setHeader(anyString(), anyString()); + verify(mockLogger, times(0)).warning(ArgumentMatchers.any(org.owasp.esapi.Logger.EventType.class),anyString(), + ArgumentMatchers.any(Exception.class)); + } + + @Test + public void testSetHeaderValueEmpty() throws Exception { + String validateNameResponse = goodHeaderName; + String validateValueResponse = " "; + PowerMockito.when(mockValidator.getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderName), + ArgumentMatchers.eq(HEADER_NAME_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false))).thenReturn(validateNameResponse); + + PowerMockito.when(mockValidator.getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderValue), + ArgumentMatchers.eq(HEADER_VALUE_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false))).thenReturn(validateValueResponse); + + PowerMockito.when(mockSecConfig.getIntProp(SEC_CTX_MAX_HEADER_NAME_SIZE_ATTR)).thenReturn( + SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH); + + PowerMockito.when(mockSecConfig.getIntProp(SEC_CTX_MAX_HEADER_VALUE_SIZE_ATTR)).thenReturn( + SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH); + + SecurityWrapperResponse response = new SecurityWrapperResponse(mockResponse); + + response.setHeader(goodHeaderName, goodHeaderValue); + + verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderName), + ArgumentMatchers.eq(HEADER_NAME_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false)); + verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderValue), + ArgumentMatchers.eq(HEADER_VALUE_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false)); + verify(mockSecConfig, times(1)).getIntProp(SEC_CTX_MAX_HEADER_NAME_SIZE_ATTR); + verify(mockSecConfig, times(1)).getIntProp(SEC_CTX_MAX_HEADER_VALUE_SIZE_ATTR); + verify(mockResponse, times(0)).setHeader(anyString(), anyString()); + verify(mockLogger, times(0)).warning(ArgumentMatchers.any(org.owasp.esapi.Logger.EventType.class),anyString(), + ArgumentMatchers.any(Exception.class)); + } + + @Test + public void testSetHeaderValueThrowsValidationException() throws Exception { + String validateNameResponse = goodHeaderName; + PowerMockito.when(mockValidator.getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderName), + ArgumentMatchers.eq(HEADER_NAME_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false))).thenReturn(validateNameResponse); + + PowerMockito.when(mockValidator.getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderValue), + ArgumentMatchers.eq(HEADER_VALUE_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false))).thenThrow(ValidationException.class); + + PowerMockito.when(mockSecConfig.getIntProp(SEC_CTX_MAX_HEADER_NAME_SIZE_ATTR)).thenReturn( + SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH); + + PowerMockito.when(mockSecConfig.getIntProp(SEC_CTX_MAX_HEADER_VALUE_SIZE_ATTR)).thenReturn( + SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH); + + SecurityWrapperResponse response = new SecurityWrapperResponse(mockResponse); + + response.setHeader(goodHeaderName, goodHeaderValue); + + verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderName), + ArgumentMatchers.eq(HEADER_NAME_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false)); + verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderValue), + ArgumentMatchers.eq(HEADER_VALUE_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false)); + verify(mockSecConfig, times(1)).getIntProp(SEC_CTX_MAX_HEADER_NAME_SIZE_ATTR); + verify(mockSecConfig, times(1)).getIntProp(SEC_CTX_MAX_HEADER_VALUE_SIZE_ATTR); + verify(mockResponse, times(0)).setHeader(anyString(), anyString()); + + verify(mockLogger, times(1)).warning(ArgumentMatchers.any(org.owasp.esapi.Logger.EventType.class), + ArgumentMatchers.contains("Attempt to set invalid header VALUE denied: HTTPHeaderName:"+ goodHeaderName), + ArgumentMatchers.any(Exception.class)); + } + + @Test + public void testAddHeaderHappyPath() throws Exception { + String validateNameResponse = goodHeaderName; + String validateValueResponse = goodHeaderValue; + PowerMockito.when(mockValidator.getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderName), + ArgumentMatchers.eq(HEADER_NAME_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false))).thenReturn(validateNameResponse); + + PowerMockito.when(mockValidator.getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderValue), + ArgumentMatchers.eq(HEADER_VALUE_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false))).thenReturn(validateValueResponse); + + PowerMockito.when(mockSecConfig.getIntProp(SEC_CTX_MAX_HEADER_NAME_SIZE_ATTR)).thenReturn( + SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH); + + PowerMockito.when(mockSecConfig.getIntProp(SEC_CTX_MAX_HEADER_VALUE_SIZE_ATTR)).thenReturn( + SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH); + + SecurityWrapperResponse response = new SecurityWrapperResponse(mockResponse); + + response.addHeader(goodHeaderName, goodHeaderValue); + + verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderName), ArgumentMatchers.eq(HEADER_NAME_CONTEXT), ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), ArgumentMatchers.eq(false)); + verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderValue), ArgumentMatchers.eq(HEADER_VALUE_CONTEXT), ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), ArgumentMatchers.eq(false)); + verify(mockSecConfig, times(1)).getIntProp(SEC_CTX_MAX_HEADER_NAME_SIZE_ATTR); + verify(mockSecConfig, times(1)).getIntProp(SEC_CTX_MAX_HEADER_VALUE_SIZE_ATTR); + verify(mockResponse, times(1)).addHeader(validateNameResponse, validateValueResponse); + verify(mockLogger,times(0)).warning(ArgumentMatchers.any(org.owasp.esapi.Logger.EventType.class), anyString(), ArgumentMatchers.any(Exception.class)); + } + + @Test + public void testAddHeaderNameNull() throws Exception { + String validateNameResponse = null; + String validateValueResponse = goodHeaderValue; + PowerMockito.when(mockValidator.getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderName), + ArgumentMatchers.eq(HEADER_NAME_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false))).thenReturn(validateNameResponse); + + PowerMockito.when(mockValidator.getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderValue), + ArgumentMatchers.eq(HEADER_VALUE_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false))).thenReturn(validateValueResponse); + + PowerMockito.when(mockSecConfig.getIntProp(SEC_CTX_MAX_HEADER_NAME_SIZE_ATTR)).thenReturn( + SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH); + + PowerMockito.when(mockSecConfig.getIntProp(SEC_CTX_MAX_HEADER_VALUE_SIZE_ATTR)).thenReturn( + SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH); + + SecurityWrapperResponse response = new SecurityWrapperResponse(mockResponse); + + response.addHeader(goodHeaderName, goodHeaderValue); + + verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderName), + ArgumentMatchers.eq(HEADER_NAME_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false)); + verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderValue), + ArgumentMatchers.eq(HEADER_VALUE_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false)); + verify(mockSecConfig, times(1)).getIntProp(SEC_CTX_MAX_HEADER_NAME_SIZE_ATTR); + verify(mockSecConfig, times(1)).getIntProp(SEC_CTX_MAX_HEADER_VALUE_SIZE_ATTR); + verify(mockResponse, times(0)).addHeader(anyString(), anyString()); + verify(mockLogger, times(0)).warning(ArgumentMatchers.any(org.owasp.esapi.Logger.EventType.class),anyString(), + ArgumentMatchers.any(Exception.class)); + } + + @Test + public void testAddHeaderNameEmpty() throws Exception { + String validateNameResponse = " "; + String validateValueResponse = goodHeaderValue; + PowerMockito.when(mockValidator.getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderName), + ArgumentMatchers.eq(HEADER_NAME_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false))).thenReturn(validateNameResponse); + + PowerMockito.when(mockValidator.getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderValue), + ArgumentMatchers.eq(HEADER_VALUE_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false))).thenReturn(validateValueResponse); + + PowerMockito.when(mockSecConfig.getIntProp(SEC_CTX_MAX_HEADER_NAME_SIZE_ATTR)).thenReturn( + SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH); + + PowerMockito.when(mockSecConfig.getIntProp(SEC_CTX_MAX_HEADER_VALUE_SIZE_ATTR)).thenReturn( + SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH); + + SecurityWrapperResponse response = new SecurityWrapperResponse(mockResponse); + + response.addHeader(goodHeaderName, goodHeaderValue); + + verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderName), + ArgumentMatchers.eq(HEADER_NAME_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false)); + verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderValue), + ArgumentMatchers.eq(HEADER_VALUE_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false)); + verify(mockSecConfig, times(1)).getIntProp(SEC_CTX_MAX_HEADER_NAME_SIZE_ATTR); + verify(mockSecConfig, times(1)).getIntProp(SEC_CTX_MAX_HEADER_VALUE_SIZE_ATTR); + verify(mockResponse, times(0)).addHeader(anyString(), anyString()); + verify(mockLogger, times(0)).warning(ArgumentMatchers.any(org.owasp.esapi.Logger.EventType.class),anyString(), + ArgumentMatchers.any(Exception.class)); + } + + @Test + public void testAddHeaderNameThrowsValidationException() throws Exception { + String validateValueResponse = goodHeaderValue; + PowerMockito.when(mockValidator.getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderName), + ArgumentMatchers.eq(HEADER_NAME_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false))).thenThrow(ValidationException.class); + + PowerMockito.when(mockValidator.getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderValue), + ArgumentMatchers.eq(HEADER_VALUE_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false))).thenReturn(validateValueResponse); + + PowerMockito.when(mockSecConfig.getIntProp(SEC_CTX_MAX_HEADER_NAME_SIZE_ATTR)).thenReturn( + SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH); + + PowerMockito.when(mockSecConfig.getIntProp(SEC_CTX_MAX_HEADER_VALUE_SIZE_ATTR)).thenReturn( + SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH); + + SecurityWrapperResponse response = new SecurityWrapperResponse(mockResponse); + + response.addHeader(goodHeaderName, goodHeaderValue); + + verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderName), + ArgumentMatchers.eq(HEADER_NAME_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false)); + verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderValue), + ArgumentMatchers.eq(HEADER_VALUE_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false)); + verify(mockSecConfig, times(1)).getIntProp(SEC_CTX_MAX_HEADER_NAME_SIZE_ATTR); + verify(mockSecConfig, times(1)).getIntProp(SEC_CTX_MAX_HEADER_VALUE_SIZE_ATTR); + verify(mockResponse, times(0)).addHeader(anyString(), anyString()); + + verify(mockLogger, times(1)).warning(ArgumentMatchers.any(org.owasp.esapi.Logger.EventType.class), + ArgumentMatchers.contains("Attempt to add invalid header NAME denied: HTTPHeaderName:"+ goodHeaderName ), + ArgumentMatchers.any(Exception.class)); + } + + @Test + public void testAddHeaderValueNull() throws Exception { + String validateNameResponse = goodHeaderName; + String validateValueResponse = null; + PowerMockito.when(mockValidator.getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderName), + ArgumentMatchers.eq(HEADER_NAME_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false))).thenReturn(validateNameResponse); + + PowerMockito.when(mockValidator.getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderValue), + ArgumentMatchers.eq(HEADER_VALUE_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false))).thenReturn(validateValueResponse); + + PowerMockito.when(mockSecConfig.getIntProp(SEC_CTX_MAX_HEADER_NAME_SIZE_ATTR)).thenReturn( + SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH); + + PowerMockito.when(mockSecConfig.getIntProp(SEC_CTX_MAX_HEADER_VALUE_SIZE_ATTR)).thenReturn( + SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH); + + SecurityWrapperResponse response = new SecurityWrapperResponse(mockResponse); + + response.addHeader(goodHeaderName, goodHeaderValue); + + verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderName), + ArgumentMatchers.eq(HEADER_NAME_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false)); + verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderValue), + ArgumentMatchers.eq(HEADER_VALUE_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false)); + verify(mockSecConfig, times(1)).getIntProp(SEC_CTX_MAX_HEADER_NAME_SIZE_ATTR); + verify(mockSecConfig, times(1)).getIntProp(SEC_CTX_MAX_HEADER_VALUE_SIZE_ATTR); + verify(mockResponse, times(0)).addHeader(anyString(), anyString()); + verify(mockLogger, times(0)).warning(ArgumentMatchers.any(org.owasp.esapi.Logger.EventType.class),anyString(), + ArgumentMatchers.any(Exception.class)); + } + + @Test + public void testAddHeaderValueEmpty() throws Exception { + String validateNameResponse = goodHeaderName; + String validateValueResponse = " "; + PowerMockito.when(mockValidator.getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderName), + ArgumentMatchers.eq(HEADER_NAME_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false))).thenReturn(validateNameResponse); + + PowerMockito.when(mockValidator.getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderValue), + ArgumentMatchers.eq(HEADER_VALUE_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false))).thenReturn(validateValueResponse); + + PowerMockito.when(mockSecConfig.getIntProp(SEC_CTX_MAX_HEADER_NAME_SIZE_ATTR)).thenReturn( + SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH); + + PowerMockito.when(mockSecConfig.getIntProp(SEC_CTX_MAX_HEADER_VALUE_SIZE_ATTR)).thenReturn( + SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH); + + SecurityWrapperResponse response = new SecurityWrapperResponse(mockResponse); + + response.addHeader(goodHeaderName, goodHeaderValue); + + verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderName), + ArgumentMatchers.eq(HEADER_NAME_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false)); + verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderValue), + ArgumentMatchers.eq(HEADER_VALUE_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false)); + verify(mockSecConfig, times(1)).getIntProp(SEC_CTX_MAX_HEADER_NAME_SIZE_ATTR); + verify(mockSecConfig, times(1)).getIntProp(SEC_CTX_MAX_HEADER_VALUE_SIZE_ATTR); + verify(mockResponse, times(0)).addHeader(anyString(), anyString()); + verify(mockLogger, times(0)).warning(ArgumentMatchers.any(org.owasp.esapi.Logger.EventType.class),anyString(), + ArgumentMatchers.any(Exception.class)); + } + + @Test + public void testAddHeaderValueThrowsValidationException() throws Exception { + String validateNameResponse = goodHeaderName; + PowerMockito.when(mockValidator.getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderName), + ArgumentMatchers.eq(HEADER_NAME_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false))).thenReturn(validateNameResponse); + + PowerMockito.when(mockValidator.getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderValue), + ArgumentMatchers.eq(HEADER_VALUE_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false))).thenThrow(ValidationException.class); + + PowerMockito.when(mockSecConfig.getIntProp(SEC_CTX_MAX_HEADER_NAME_SIZE_ATTR)).thenReturn( + SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH); + + PowerMockito.when(mockSecConfig.getIntProp(SEC_CTX_MAX_HEADER_VALUE_SIZE_ATTR)).thenReturn( + SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH); + + SecurityWrapperResponse response = new SecurityWrapperResponse(mockResponse); + + response.addHeader(goodHeaderName, goodHeaderValue); + + verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderName), + ArgumentMatchers.eq(HEADER_NAME_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false)); + verify(mockValidator, times(1)).getValidInput(anyString(), ArgumentMatchers.eq(goodHeaderValue), + ArgumentMatchers.eq(HEADER_VALUE_CONTEXT), + ArgumentMatchers.eq(SecurityWrapperRequestTest.SECURITY_CONFIGURATION_TEST_LENGTH), + ArgumentMatchers.eq(false)); + verify(mockSecConfig, times(1)).getIntProp(SEC_CTX_MAX_HEADER_NAME_SIZE_ATTR); + verify(mockSecConfig, times(1)).getIntProp(SEC_CTX_MAX_HEADER_VALUE_SIZE_ATTR); + verify(mockResponse, times(0)).addHeader(anyString(), anyString()); + + verify(mockLogger, times(1)).warning(ArgumentMatchers.any(org.owasp.esapi.Logger.EventType.class), + ArgumentMatchers.contains("Attempt to add invalid header VALUE denied: HTTPHeaderName:"+ goodHeaderName), + ArgumentMatchers.any(Exception.class)); + } + + @Test + public void testAddRefererHeader(){ + HttpServletResponse servResp = mock(HttpServletResponse.class); + SecurityWrapperResponse resp = new SecurityWrapperResponse(servResp); + resp.addReferer("http://127.0.0.1:3000/campaigns?goal=all§ion=active&sort-by=-id&status=Draft%2CLaunched"); + verify(servResp, times(1)).addHeader("referer", ""); + } + + @Test + public void testAddDateHeader(){ + HttpServletResponse servResp = mock(HttpServletResponse.class); + SecurityWrapperResponse resp = new SecurityWrapperResponse(servResp); + long currentTime = System.currentTimeMillis(); + resp.addDateHeader("Foo", currentTime); + verify(servResp, times(1)).addDateHeader("Foo", currentTime); + } + + @Test + public void testSetDateHeader(){ + HttpServletResponse servResp = mock(HttpServletResponse.class); + SecurityWrapperResponse resp = new SecurityWrapperResponse(servResp); + long currentTime = System.currentTimeMillis(); + resp.setDateHeader("Foo", currentTime); + verify(servResp, times(1)).setDateHeader("Foo", currentTime); + } + + @Test + public void testSetInvalidDateHeader(){ + HttpServletResponse servResp = mock(HttpServletResponse.class); + SecurityWrapperResponse resp = new SecurityWrapperResponse(servResp); + long currentTime = System.currentTimeMillis(); + resp.setDateHeader("alert"); + verify(servResp, times(0)).setHeader("foo", ""); + } + + @Test + public void testInvalidDateHeader(){ + HttpServletResponse servResp = mock(HttpServletResponse.class); + SecurityWrapperResponse resp = new SecurityWrapperResponse(servResp); + long currentTime = System.currentTimeMillis(); + resp.addDateHeader("Foo\\r\\n", currentTime); + verify(servResp, times(0)).addDateHeader("Foo", currentTime); + } + + @Test + public void testAddHeaderInvalidValueLength(){ + //refactor this to use a spy. + HttpServletResponse servResp = mock(HttpServletResponse.class); + SecurityWrapperResponse resp = new SecurityWrapperResponse(servResp); + SecurityWrapperResponse spyResp = spy(resp); + Mockito.doCallRealMethod().when(spyResp).addHeader("Foo", TestUtils.generateStringOfLength(4097)); + resp.addHeader("Foo", TestUtils.generateStringOfLength(4097)); + verify(servResp, times(0)).addHeader("Foo", "bar"); + } + + @Test + public void testAddHeaderInvalidKeyLength(){ + HttpServletResponse servResp = mock(HttpServletResponse.class); + SecurityWrapperResponse resp = new SecurityWrapperResponse(servResp); + resp.addHeader(TestUtils.generateStringOfLength(257), "bar"); + verify(servResp, times(0)).addHeader("Foo", "bar"); + } + + @Test + public void testAddIntHeader(){ + HttpServletResponse servResp = mock(HttpServletResponse.class); + SecurityWrapperResponse resp = new SecurityWrapperResponse(servResp); + resp.addIntHeader("aaaa", 4); + verify(servResp, times(1)).addIntHeader("aaaa", 4); + } + + @Test + public void testAddInvalidIntHeader(){ + HttpServletResponse servResp = mock(HttpServletResponse.class); + SecurityWrapperResponse resp = new SecurityWrapperResponse(servResp); + resp.addIntHeader(TestUtils.generateStringOfLength(257), Integer.MIN_VALUE); + verify(servResp, times(0)).addIntHeader(TestUtils.generateStringOfLength(257), Integer.MIN_VALUE); + } + + @Test + public void testContainsHeader(){ + HttpServletResponse servResp = new MockHttpServletResponse(); + servResp = spy(servResp); + SecurityWrapperResponse resp = new SecurityWrapperResponse(servResp); + resp = spy(resp); + resp.addIntHeader("aaaa", Integer.MIN_VALUE); + verify(servResp, times(1)).addIntHeader("aaaa", Integer.MIN_VALUE); + assertEquals(true, servResp.containsHeader("aaaa")); + } + + @Test + public void testAddValidCookie(){ + HttpServletResponse servResp = new MockHttpServletResponse(); + servResp = spy(servResp); + SecurityWrapperResponse resp = new SecurityWrapperResponse(servResp); + SecurityWrapperResponse spyResp = spy(resp); + Cookie cookie = new Cookie("Foo", TestUtils.generateStringOfLength(10)); + cookie.setMaxAge(5000); + Mockito.doCallRealMethod().when(spyResp).addCookie(cookie); + spyResp.addCookie(cookie); + + /* + * We're indirectly testing our class. Since it ultimately + * delegates to HttpServletResponse.addHeader, we're actually + * validating that our test method constructs a header with the + * expected properties. This implicitly tests the + * createCookieHeader method as well. + */ + verify(servResp, times(1)).addHeader("Set-Cookie", "Foo=aaaaaaaaaa; Max-Age=5000; Secure; HttpOnly"); + } + + @Test + public void testAddValidCookieWithDomain(){ + HttpServletResponse servResp = new MockHttpServletResponse(); + servResp = spy(servResp); + SecurityWrapperResponse resp = new SecurityWrapperResponse(servResp); + SecurityWrapperResponse spyResp = spy(resp); + Cookie cookie = new Cookie("Foo", TestUtils.generateStringOfLength(10)); + cookie.setDomain("evil.com"); + cookie.setMaxAge(-1); + Mockito.doCallRealMethod().when(spyResp).addCookie(cookie); + spyResp.addCookie(cookie); + verify(servResp, times(1)).addHeader("Set-Cookie", "Foo=aaaaaaaaaa; Domain=evil.com; Secure; HttpOnly"); + } + + @Test + public void testAddValidCookieWithPath(){ + HttpServletResponse servResp = new MockHttpServletResponse(); + servResp = spy(servResp); + SecurityWrapperResponse resp = new SecurityWrapperResponse(servResp); + SecurityWrapperResponse spyResp = spy(resp); + Cookie cookie = new Cookie("Foo", TestUtils.generateStringOfLength(10)); + cookie.setDomain("evil.com"); + cookie.setPath("/foo/bar"); + Mockito.doCallRealMethod().when(spyResp).addCookie(cookie); + spyResp.addCookie(cookie); + verify(servResp, times(1)).addHeader("Set-Cookie", "Foo=aaaaaaaaaa; Domain=evil.com; Path=/foo/bar; Secure; HttpOnly"); + } + + @Test + public void testAddInValidCookie(){ + HttpServletResponse servResp = new MockHttpServletResponse(); + servResp = spy(servResp); + SecurityWrapperResponse resp = new SecurityWrapperResponse(servResp); + SecurityWrapperResponse spyResp = spy(resp); + Cookie cookie = new Cookie("Foo", TestUtils.generateStringOfLength(5000)); + Mockito.doCallRealMethod().when(spyResp).addCookie(cookie); + + spyResp.addCookie(cookie); + verify(servResp, times(0)).addHeader("Set-Cookie", "Foo=" + TestUtils.generateStringOfLength(5000) + "; Secure; HttpOnly"); + } + + @Test + public void testSendError() throws Exception{ + HttpServletResponse servResp = new MockHttpServletResponse(); + servResp = spy(servResp); + SecurityWrapperResponse resp = new SecurityWrapperResponse(servResp); + SecurityWrapperResponse spyResp = spy(resp); + Mockito.doCallRealMethod().when(spyResp).sendError(200); + spyResp.sendError(200); + + verify(servResp, times(1)).sendError(200, "HTTP error code: 200");; + } + + @Test + public void testSendStatus() throws Exception{ + HttpServletResponse servResp = new MockHttpServletResponse(); + servResp = spy(servResp); + SecurityWrapperResponse resp = new SecurityWrapperResponse(servResp); + SecurityWrapperResponse spyResp = spy(resp); + Mockito.doCallRealMethod().when(spyResp).setStatus(200);; + spyResp.setStatus(200); + + verify(servResp, times(1)).setStatus(200);; + } + + @Test + public void testSendStatusWithString() throws Exception{ + HttpServletResponse servResp = new MockHttpServletResponse(); + servResp = spy(servResp); + SecurityWrapperResponse resp = new SecurityWrapperResponse(servResp); + SecurityWrapperResponse spyResp = spy(resp); + Mockito.doCallRealMethod().when(spyResp).setStatus(200, "foo");; + spyResp.setStatus(200, "foo"); + + verify(servResp, times(1)).sendError(200, "foo");; + } +} diff --git a/src/test/java/org/owasp/esapi/http/MockFilterChain.java b/src/test/java/org/owasp/esapi/http/MockFilterChain.java new file mode 100644 index 000000000..c00927e35 --- /dev/null +++ b/src/test/java/org/owasp/esapi/http/MockFilterChain.java @@ -0,0 +1,46 @@ +/** + * 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.http; + +import java.io.IOException; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + * @author jwilliams + */ +public class MockFilterChain implements FilterChain { + /** + * + * @param request + * @param response + * @throws java.io.IOException + * @throws javax.servlet.ServletException + */ + public void doFilter( ServletRequest request, ServletResponse response ) throws IOException, ServletException { + System.out.println( "CHAIN received " + request.getClass().getName() + " and is issuing " + response.getClass().getName() ); + response.getOutputStream().println( " This is the body of a response for " + ((HttpServletRequest)request).getRequestURI() ); + ((HttpServletResponse)response).addCookie( new Cookie( "name", "value" ) ); + } + +} diff --git a/src/test/java/org/owasp/esapi/http/MockFilterConfig.java b/src/test/java/org/owasp/esapi/http/MockFilterConfig.java new file mode 100644 index 000000000..7f350f977 --- /dev/null +++ b/src/test/java/org/owasp/esapi/http/MockFilterConfig.java @@ -0,0 +1,66 @@ +/** + * 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.http; + +import java.util.Collections; +import java.util.Enumeration; +import java.util.Map; + +import javax.servlet.FilterConfig; +import javax.servlet.ServletContext; + +/** + * A filter configuration object used by a servlet container + * to pass information to a filter during initialization. + */ +public class MockFilterConfig implements FilterConfig { + private Map map; + + public MockFilterConfig( Map map ) { + this.map = map; + } + + public String getFilterName() { + return "mock"; + } + + /** + * Returns a reference to the {@link ServletContext} in which the caller + * is executing. + */ + public ServletContext getServletContext() { + return new MockServletContext(); + } + + /** + * Returns a String containing the value of the + * named initialization parameter, or null if + * the parameter does not exist. + */ + public String getInitParameter(String name) { + return (String)map.get( name ); + } + + /** + * Returns the names of the filter's initialization parameters + * as an Enumeration of String objects, + * or an empty Enumeration if the filter has + * no initialization parameters. + */ + public Enumeration getInitParameterNames() { + return Collections.enumeration( map.keySet() ); + } +} diff --git a/src/test/java/org/owasp/esapi/http/MockHttpServletRequest.java b/src/test/java/org/owasp/esapi/http/MockHttpServletRequest.java new file mode 100644 index 000000000..d64b00598 --- /dev/null +++ b/src/test/java/org/owasp/esapi/http/MockHttpServletRequest.java @@ -0,0 +1,756 @@ +/** + * 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.http; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URL; +import java.security.Principal; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Vector; +import javax.servlet.AsyncContext; +import javax.servlet.DispatcherType; + +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletInputStream; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import javax.servlet.http.HttpUpgradeHandler; +import javax.servlet.http.Part; + +/** + * The Class MockHttpServletRequest. + * + * @author jwilliams + */ +public class MockHttpServletRequest implements HttpServletRequest +{ + private static final String HDR_CONTENT_TYPE = "Content-Type"; + private static final String[] EMPTY_STRING_ARRAY = new String[0]; + + /** The requestDispatcher */ + private RequestDispatcher requestDispatcher = new MockRequestDispatcher(); + + /** The session. */ + private MockHttpSession session = null; + + /** The cookies. */ + private ArrayList cookies = new ArrayList(); + + /** The parameters. */ + private Map parameters = new HashMap(); + + /** The headers. */ + private Map> headers = new HashMap>(); + + private byte[] body; + + private String scheme = "https"; + + private String remoteHost = "64.14.103.52"; + + private String serverHost = "64.14.103.52"; + + private String uri = "/test"; + + private String queryString = "pid=1&qid=test"; + + private String method = "POST"; + + private Map attrs = new HashMap(); + + public MockHttpServletRequest() { + } + + public MockHttpServletRequest(String uri, byte[] body) { + this.body = body; + this.uri = uri; + } + + public MockHttpServletRequest( URL url ) { + scheme = url.getProtocol(); + serverHost = url.getHost(); + uri = url.getPath(); + } + + public String getAuthType() { + return null; + } + + public String getContextPath() { + return null; + } + + /** + * Adds the parameter. + * + * @param name the name + * @param value the value + */ + public void addParameter(String name, String value) { + String[] old = parameters.get(name); + if ( old == null ) { + old = new String[0]; + } + String[] updated = new String[old.length + 1]; + for ( int i = 0; i < old.length; i++ ) updated[i] = old[i]; + updated[old.length] = value; + parameters.put(name, updated); + } + + /** + * removeParameter removes the parameter name from the parameters map if it exists + * + * @param name + * parameter name to be removed + */ + public void removeParameter( String name ) { + parameters.remove( name ); + } + + /** + * Adds the header. + * + * @param name the name + * @param value the value + */ + public void addHeader(String name, String value) + { + List values; + + if((values = headers.get(name))==null) + { + values = new ArrayList(); + headers.put(name, values); + } + values.add(value); + } + + /** + * Set a header replacing any previous value(s). + * @param name the header name + * @param value the header value + */ + public void setHeader(String name, String value) + { + List values = new ArrayList(); + + values.add(value); + headers.put(name,values); + } + + /** + * Sets the cookies. + * + * @param list the new cookies + */ + public void setCookies(ArrayList list) { + cookies = list; + } + + public void setCookie(String name, String value ) { + Cookie c = new Cookie( name, value ); + cookies.add( c ); + } + + public boolean clearCookie(String name) { + return cookies.remove(name); + } + + public void clearCookies() { + cookies.clear(); + } + + /** + * {@inheritDoc} + */ + public Cookie[] getCookies() { + if ( cookies.isEmpty() ) return null; + return cookies.toArray(new Cookie[0]); + } + + /** + * {@inheritDoc} + */ + public long getDateHeader(String name) { + try { + Date date = SimpleDateFormat.getDateTimeInstance().parse( getParameter( name ) ); + return date.getTime(); // TODO needs to be HTTP format + } catch( ParseException e ) { + return 0; + } + } + + /** + * {@inheritDoc} + * @param name + * @return The requested header value. + */ + public String getHeader(String name) { + List values; + + if((values = headers.get(name))==null) + return null; + if(values.size() == 0) + return null; + return values.get(0); + } + + /** + * {@inheritDoc} + * @return Enumeration of header names as strings + */ + public Enumeration getHeaderNames() + { + return Collections.enumeration(headers.keySet()); + } + + /** + * {@inheritDoc} + */ + public Enumeration getHeaders(String name) { + Vector v = new Vector(); + v.add( getHeader( name ) ); + return v.elements(); + } + + /** + * {@inheritDoc} + */ + public int getIntHeader(String name) { + + return 0; + } + + /** + * {@inheritDoc} + */ + public String getMethod() { + return method; + } + + public void setMethod( String value ) { + method = value; + } + + /** + * {@inheritDoc} + */ + public String getPathInfo() { + + return null; + } + + /** + * {@inheritDoc} + */ + public String getPathTranslated() { + + return null; + } + + /** + * {@inheritDoc} + */ + public String getQueryString() { + return queryString; + } + + /** + * Set the query string to return. + * @param str The query string to return. + */ + public void setQueryString(String str) + { + this.queryString = str; + } + + /** + * {@inheritDoc} + */ + public String getRemoteUser() { + + return null; + } + + /** + * {@inheritDoc} + */ + public String getRequestURI() { + return uri; + } + + /** + * {@inheritDoc} + */ + public StringBuffer getRequestURL() { + return new StringBuffer( getScheme() + "://" + this.getServerName() + getRequestURI() + "?" + getQueryString() ); + } + + /** + * {@inheritDoc} + */ + public String getRequestedSessionId() { + + return null; + } + + /** + * {@inheritDoc} + */ + public String getServletPath() { + + return null; + } + + /** + * {@inheritDoc} + */ + public HttpSession getSession() { + if (session != null) { + return getSession(false); + } + return getSession(true); + } + + /** + * {@inheritDoc} + */ + public HttpSession getSession(boolean create) { + if (session == null && create) { + session = new MockHttpSession(); + } else if (session != null && session.getInvalidated()) { + session = new MockHttpSession(); + } + return session; + } + + /** + * {@inheritDoc} + */ + public Principal getUserPrincipal() { + + return null; + } + + /** + * {@inheritDoc} + */ + public boolean isRequestedSessionIdFromCookie() { + + return false; + } + + /** + * {@inheritDoc} + */ + public boolean isRequestedSessionIdFromURL() { + + return false; + } + + /** + * {@inheritDoc} + * @deprecated + */ + @Deprecated + public boolean isRequestedSessionIdFromUrl() { + + return false; + } + + /** + * {@inheritDoc} + */ + public boolean isRequestedSessionIdValid() { + + return false; + } + + /** + * {@inheritDoc} + */ + public boolean isUserInRole(String role) { + + return false; + } + + /** + * {@inheritDoc} + */ + public Object getAttribute(String name) { + return attrs.get(name); + } + + /** + * {@inheritDoc} + */ + public Enumeration getAttributeNames() { + return Collections.enumeration(attrs.keySet()); + } + + /** + * {@inheritDoc} + */ + public String getCharacterEncoding() { + + return null; + } + + /** + * {@inheritDoc} + */ + public int getContentLength() { + return body.length; + } + + /** + * {@inheritDoc} + */ + public String getContentType() { + return getHeader(HDR_CONTENT_TYPE); + } + + public void setContentType( String value ) { + setHeader(HDR_CONTENT_TYPE, value); + } + + /** + * {@inheritDoc} + */ + public ServletInputStream getInputStream() throws IOException { + return new MockServletInputStream(body); + } + + /** + * {@inheritDoc} + */ + public String getLocalAddr() { + return "10.1.43.6"; + } + + /** + * {@inheritDoc} + */ + public String getLocalName() { + return "www.domain.com"; + } + + /** + * {@inheritDoc} + */ + public int getLocalPort() { + return 80; + } + + /** + * {@inheritDoc} + */ + public Locale getLocale() { + return null; + } + + /** + * {@inheritDoc} + */ + public Enumeration getLocales() { + return null; + } + + /** + * {@inheritDoc} + */ + public String getParameter(String name) { + String[] values = parameters.get(name); + if ( values == null ) return null; + return values[0]; + } + + public void clearParameter(String name) { + parameters.remove( name ); + } + + public void clearParameters() { + parameters.clear(); + } + + /** + * {@inheritDoc} + */ + public Map getParameterMap() { + return parameters; + } + + /** + * {@inheritDoc} + */ + public Enumeration getParameterNames() { + return Collections.enumeration(parameters.keySet()); + } + + /** + * {@inheritDoc} + */ + public String[] getParameterValues(String name) { + return parameters.get(name); + } + + /** + * {@inheritDoc} + */ + public String getProtocol() { + return "HTTP/1.1"; + } + + /** + * {@inheritDoc} + */ + public BufferedReader getReader() throws IOException { + + return null; + } + + /** + * {@inheritDoc} + * @deprecated + */ + @Deprecated + public String getRealPath(String path) { + + return null; + } + + /** + * {@inheritDoc} + */ + public String getRemoteAddr() { + return remoteHost; + } + + public void setRemoteAddr(String remoteHost) { + this.remoteHost = remoteHost; + } + + /** + * {@inheritDoc} + */ + public String getRemoteHost() { + return remoteHost; + } + + /** + * {@inheritDoc} + */ + public int getRemotePort() { + + return 0; + } + + /** + * {@inheritDoc} + */ + public RequestDispatcher getRequestDispatcher(String path) { + return requestDispatcher; + } + + /** + * {@inheritDoc} + */ + public String getScheme() { + return scheme; + } + + /** + * {@inheritDoc} + */ + public String getServerName() { + return serverHost; + } + + /** + * {@inheritDoc} + */ + public int getServerPort() { + return 80; + } + + /** + * {@inheritDoc} + */ + public boolean isSecure() { + return scheme.equals( "https" ); + } + + /** + * {@inheritDoc} + */ + public void removeAttribute(String name) { + attrs.remove(name); + } + + /** + * {@inheritDoc} + */ + public void setAttribute(String name, Object o) { + attrs.put(name,o); + } + + /** + * {@inheritDoc} + */ + public void setCharacterEncoding(String env) throws UnsupportedEncodingException { + + } + + public void setRequestURI(String uri) throws UnsupportedEncodingException { + this.uri = uri; + } + + public void setRequestURL(String url) throws UnsupportedEncodingException { + // get the scheme + int p = url.indexOf( ":" ); + this.scheme = url.substring( 0, p ); + + // get the queryString + int q = url.indexOf( "?" ); + if ( q != -1 ) + { + queryString = url.substring( q+1 ); + url = url.substring( 0, q ); + } + else + queryString = null; + } + + public void setScheme( String scheme ) { + this.scheme = scheme; + } + + public void dump() + { + String[] names; + + System.out.println(); + System.out.println( " " + this.getMethod() + " " + this.getRequestURL() ); + + names = headers.keySet().toArray(EMPTY_STRING_ARRAY); + Arrays.sort(names); // make debugging a bit easier... + for (String name : names) + for(String value : headers.get(name)) + System.out.println( " " + name + ": " + value); + names = parameters.keySet().toArray(EMPTY_STRING_ARRAY); + Arrays.sort(names); + for (String name : names) { + for(String value : parameters.get(name)) + System.out.println( " " + name + "=" + value); + } + System.out.println( "\n" ); + } + + @Override + public boolean authenticate(HttpServletResponse hsr) throws IOException, ServletException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void login(String string, String string1) throws ServletException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void logout() throws ServletException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public Collection getParts() throws IOException, ServletException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public Part getPart(String string) throws IOException, ServletException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public ServletContext getServletContext() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public AsyncContext startAsync() throws IllegalStateException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public AsyncContext startAsync(ServletRequest sr, ServletResponse sr1) throws IllegalStateException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public boolean isAsyncStarted() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public boolean isAsyncSupported() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public AsyncContext getAsyncContext() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public DispatcherType getDispatcherType() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public long getContentLengthLong() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public String changeSessionId() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public T upgrade(Class handlerClass) throws IOException, ServletException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + +} diff --git a/src/test/java/org/owasp/esapi/http/MockHttpServletResponse.java b/src/test/java/org/owasp/esapi/http/MockHttpServletResponse.java new file mode 100644 index 000000000..fadfe13f6 --- /dev/null +++ b/src/test/java/org/owasp/esapi/http/MockHttpServletResponse.java @@ -0,0 +1,389 @@ +/** + * 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.http; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; + +import javax.servlet.ServletOutputStream; +import javax.servlet.WriteListener; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletResponse; + +import org.owasp.esapi.ESAPI; + +/** + * The Class MockHttpServletResponse. + * + * @author jwilliams + */ +public class MockHttpServletResponse implements HttpServletResponse { + + /** The cookies. */ + List cookies = new ArrayList(); + + /** The header names. */ + List headerNames = new ArrayList(); + + /** The header values. */ + List headerValues = new ArrayList(); + + /** The status. */ + int status = 200; + + StringBuffer body = new StringBuffer(); + + String contentType = "text/html; charset=ISO-8895-1"; + + public String getBody() { + return body.toString(); + } + + /** + * {@inheritDoc} + */ + public void addCookie(Cookie cookie) { + cookies.add(cookie); + } + + public List getCookies() { + return cookies; + } + + public Cookie getCookie(String name) { + Iterator i = cookies.iterator(); + while (i.hasNext()) { + Cookie c = i.next(); + if (c.getName().equals(name)) { + return c; + } + } + return null; + } + + /** + * {@inheritDoc} + */ + public void addDateHeader(String name, long date) { + headerNames.add(name); + headerValues.add("" + date); + } + + /** + * {@inheritDoc} + */ + public void addHeader(String name, String value) { + headerNames.add(name); + headerValues.add(value); + } + + /** + * {@inheritDoc} + */ + public void addIntHeader(String name, int value) { + headerNames.add(name); + headerValues.add("" + value); + } + + /** + * {@inheritDoc} + */ + public boolean containsHeader(String name) { + return headerNames.contains(name); + } + + /** + * {@inheritDoc} + */ + public String getHeader(String name) { + int index = headerNames.indexOf(name); + if (index != -1) { + return headerValues.get(index); + } + return null; + } + + /** + * Gets the header names. + * + * @return the header names + */ + public List getHeaderNames() { + return headerNames; + } + + /** + * {@inheritDoc} + */ + public String encodeRedirectURL(String url) { + return null; + } + + /** + * {@inheritDoc} + * @deprecated + */ + @Deprecated + public String encodeRedirectUrl(String url) { + return null; + } + + /** + * {@inheritDoc} + */ + public String encodeURL(String url) { + String enc = url; + try { enc = ESAPI.encoder().encodeForURL(url); + } catch( Exception e ) {} + return enc; + } + + /** + * {@inheritDoc} + * @deprecated + */ + @Deprecated + public String encodeUrl(String url) { + return encodeURL( url ); + } + + /** + * {@inheritDoc} + */ + public void sendError(int sc) throws IOException { + status = sc; + } + + /** + * {@inheritDoc} + */ + public void sendError(int sc, String msg) throws IOException { + status = sc; + } + + /** + * {@inheritDoc} + */ + public void sendRedirect(String location) throws IOException { + status = HttpServletResponse.SC_MOVED_PERMANENTLY; + body = new StringBuffer( "Redirect to " + location ); + } + + /** + * {@inheritDoc} + */ + public void setDateHeader(String name, long date) { + headerNames.add(name); + headerValues.add("" + date); + } + + /** + * {@inheritDoc} + */ + public void setHeader(String name, String value) { + headerNames.add(name); + headerValues.add(value); + } + + /** + * {@inheritDoc} + */ + public void setIntHeader(String name, int value) { + headerNames.add(name); + headerValues.add("" + value); + } + + /** + * {@inheritDoc} + */ + public void setStatus(int sc) { + status = sc; + } + + /** + * Gets the status. + * + * @return the status + */ + public int getStatus() { + return status; + } + + /** + * {@inheritDoc} + * @deprecated + */ + @Deprecated + public void setStatus(int sc, String sm) { + status = sc; + } + + /** + * {@inheritDoc} + */ + public void flushBuffer() throws IOException { + + } + + /** + * {@inheritDoc} + */ + public int getBufferSize() { + return body.length(); + } + + /** + * {@inheritDoc} + */ + public String getCharacterEncoding() { + return "UTF-8"; + } + + /** + * {@inheritDoc} + */ + public String getContentType() { + return contentType; + } + + /** + * {@inheritDoc} + */ + public Locale getLocale() { + + return null; + } + + /** + * {@inheritDoc} + */ + public ServletOutputStream getOutputStream() throws IOException { + return new ServletOutputStream() { + public void write(int b) throws IOException { + body.append((char)b); + } + + @Override + public boolean isReady() { + return false; + } + + @Override + public void setWriteListener(WriteListener writeListener) { + //NO-OP + } + }; + } + + /** + * {@inheritDoc} + */ + public PrintWriter getWriter() throws IOException { + return new PrintWriter( getOutputStream(), true ); + } + + /** + * {@inheritDoc} + */ + public boolean isCommitted() { + + return false; + } + + /** + * {@inheritDoc} + */ + public void reset() { + body = new StringBuffer(); + cookies = new ArrayList(); + headerNames = new ArrayList(); + headerValues = new ArrayList(); + status = 200; + } + + /** + * {@inheritDoc} + */ + public void resetBuffer() { + body = new StringBuffer(); + } + + public void setBody( String value ) { + body = new StringBuffer( value ); + } + + /** + * {@inheritDoc} + */ + public void setBufferSize(int size) { + + } + + /** + * {@inheritDoc} + */ + public void setCharacterEncoding(String charset) { + + } + + /** + * {@inheritDoc} + */ + public void setContentLength(int len) { + + } + + /** + * {@inheritDoc} + */ + public void setContentType(String type) { + contentType = type; + } + + /** + * {@inheritDoc} + */ + public void setLocale(Locale loc) { + + } + + /* + * Dump the response in a semi-readable format close to a real HTTP response on the wire + */ + public void dump() { + System.out.println(); + System.out.println( " " + this.getStatus() + " " ); + for ( Object name : getHeaderNames() ) System.out.println( " " + name + "=" + getHeader( (String)name ) ); + System.out.println( " BODY: " + this.getBody() ); + System.out.println(); + } + + @Override + public Collection getHeaders(String string) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void setContentLengthLong(long len) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + +} diff --git a/src/test/java/org/owasp/esapi/http/MockHttpSession.java b/src/test/java/org/owasp/esapi/http/MockHttpSession.java new file mode 100644 index 000000000..ef716fee2 --- /dev/null +++ b/src/test/java/org/owasp/esapi/http/MockHttpSession.java @@ -0,0 +1,231 @@ +/** + * 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.http; + +import java.util.Date; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.Vector; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpSession; + +/** + * The Class MockHttpSession. + * + * @author jwilliams + */ +public class MockHttpSession implements HttpSession { + + /** The invalidated. */ + boolean invalidated = false; + + /** The creation time. */ + private long creationTime=new Date().getTime(); + + /** The accessed time. */ + private long accessedTime=new Date().getTime(); + + /** The count. */ + private static int count = 1; + + /** The sessionid. */ + private int sessionid=count++; + + /** The attributes. */ + private Map attributes = new HashMap(); + + /** + * Instantiates a new test HTTP session. + */ + public MockHttpSession() { + // to replace synthetic accessor method + } + + /** + * Instantiates a new test http session. + * + * @param creationTime + * the creation time + * @param accessedTime + * the accessed time + */ + public MockHttpSession( long creationTime, long accessedTime ) { + this.creationTime = creationTime; + this.accessedTime = accessedTime; + } + + /** + * {@inheritDoc} + */ + public Object getAttribute(String string) { + return attributes.get( string ); + } + + /** + * {@inheritDoc} + */ + public Enumeration getAttributeNames() { + Vector v = new Vector( attributes.keySet() ); + return v.elements(); + } + + /** + * {@inheritDoc} + */ + public long getCreationTime() { + return creationTime; + } + + /** + * {@inheritDoc} + */ + public String getId() { + return ""+sessionid; + } + + /** + * Gets the invalidated. + * + * @return the invalidated + */ + public boolean getInvalidated() { + return invalidated; + } + + /** + * {@inheritDoc} + */ + public long getLastAccessedTime() { + return accessedTime; + } + + /** + * {@inheritDoc} + */ + public int getMaxInactiveInterval() { + return 0; + } + + /** + * {@inheritDoc} + */ + public ServletContext getServletContext() { + return null; + } + + /** + * {@inheritDoc} + * @deprecated + */ + @Deprecated + // need the full class here as for whatever stupid reason you can't + // seem to @SuppressWarnings{'deprecation'} on the import... *sigh* + public javax.servlet.http.HttpSessionContext getSessionContext() { + return null; + } + + /** + * {@inheritDoc} + * @deprecated + */ + @Deprecated + public Object getValue(String string) { + return null; + } + + /** + * {@inheritDoc} + * @deprecated + */ + @Deprecated + public String[] getValueNames() { + return null; + } + + /** + * {@inheritDoc} + */ + public void invalidate() { + invalidated = true; + } + + /** + * {@inheritDoc} + */ + public boolean isNew() { + return true; + } + + /** + * {@inheritDoc} + * @deprecated + */ + @Deprecated + public void putValue(String string, Object object) { + setAttribute( string, object ); + } + + /** + * {@inheritDoc} + */ + public void removeAttribute(String string) { + attributes.remove( string ); + } + + /** + * {@inheritDoc} + * @deprecated + */ + @Deprecated + public void removeValue(String string) { + removeAttribute( string ); + } + + /** + * {@inheritDoc} + */ + public void setAttribute(String string, Object object) { + attributes.put(string, object); + } + + /** + * {@inheritDoc} += */ + public void setMaxInactiveInterval(int i) { + // stub + } + + /** + * + * @param time + */ + public void setAccessedTime( long time ) { + this.accessedTime = time; + } + + + /** + * + * @param time + */ + public void setCreationTime( long time ) { + this.creationTime = time; + } + +} + diff --git a/src/test/java/org/owasp/esapi/http/MockRequestDispatcher.java b/src/test/java/org/owasp/esapi/http/MockRequestDispatcher.java new file mode 100644 index 000000000..d0117ce8d --- /dev/null +++ b/src/test/java/org/owasp/esapi/http/MockRequestDispatcher.java @@ -0,0 +1,54 @@ +/** + * 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.http; + +import java.io.IOException; + +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +/** + * + * @author jwilliams + */ +public class MockRequestDispatcher implements RequestDispatcher { + + /** + * + * @param request + * @param response + * @throws javax.servlet.ServletException + * @throws java.io.IOException + */ + public void forward(ServletRequest request, ServletResponse response) throws ServletException, IOException { + System.out.println( "Forwarding" ); + } + + /** + * + * @param request + * @param response + * @throws javax.servlet.ServletException + * @throws java.io.IOException + */ + public void include(ServletRequest request, ServletResponse response) throws ServletException, IOException { + System.out.println( "Including" ); + } +} + + diff --git a/src/test/java/org/owasp/esapi/http/MockServletContext.java b/src/test/java/org/owasp/esapi/http/MockServletContext.java new file mode 100644 index 000000000..062577090 --- /dev/null +++ b/src/test/java/org/owasp/esapi/http/MockServletContext.java @@ -0,0 +1,701 @@ +/** + * 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.http; + +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Enumeration; +import java.util.EventListener; +import java.util.Map; +import java.util.Set; +import javax.servlet.Filter; +import javax.servlet.FilterRegistration; + +import javax.servlet.RequestDispatcher; +import javax.servlet.Servlet; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRegistration; +import javax.servlet.SessionCookieConfig; +import javax.servlet.SessionTrackingMode; +import javax.servlet.descriptor.JspConfigDescriptor; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Logger; + +/** + * Defines a set of methods that a servlet uses to communicate with its + * servlet container, for example, to get the MIME type of a file, dispatch + * requests, or write to a log file. + * + *

There is one context per "web application" per Java Virtual Machine. (A + * "web application" is a collection of servlets and content installed under a + * specific subset of the server's URL namespace such as /catalog + * and possibly installed via a .war file.) + * + *

In the case of a web + * application marked "distributed" in its deployment descriptor, there will + * be one context instance for each virtual machine. In this situation, the + * context cannot be used as a location to share global information (because + * the information won't be truly global). Use an external resource like + * a database instead. + * + *

The ServletContext object is contained within + * the {@link ServletConfig} object, which the Web server provides the + * servlet when the servlet is initialized. + * + * @see Servlet#getServletConfig + * @see ServletConfig#getServletContext + * + * @version $Rev: 46019 $ $Date: 2004-09-14 04:56:06 -0500 (Tue, 14 Sep 2004) $ + */ +public class MockServletContext implements ServletContext { + @Override + public String getContextPath() { + return "/"; + } + + /** + * Returns a ServletContext object that + * corresponds to a specified URL on the server. + * + *

This method allows servlets to gain + * access to the context for various parts of the server, and as + * needed obtain {@link RequestDispatcher} objects from the context. + * The given path must be begin with "/", is interpreted relative + * to the server's document root and is matched against the context roots of + * other web applications hosted on this container. + * + *

In a security conscious environment, the servlet container may + * return null for a given URL. + * + * @param uripath a String specifying the context path of + * another web application in the container. + * @return the ServletContext object that + * corresponds to the named URL, or null if either none exists or the + * container wishes to restrict this access. + * + * @see RequestDispatcher + */ + public ServletContext getContext(String uripath) { + return null; + } + + /** + * Returns the major version of the Java Servlet API that this + * servlet container supports. All implementations that comply + * with Version 2.4 must have this method + * return the integer 2. + * + * @return 2 + */ + public int getMajorVersion() { + return 2; + } + + /** + * Returns the minor version of the Servlet API that this + * servlet container supports. All implementations that comply + * with Version 2.4 must have this method + * return the integer 4. + */ + public int getMinorVersion() { + return 4; + } + + /** + * Returns the MIME type of the specified file, or null if + * the MIME type is not known. The MIME type is determined + * by the configuration of the servlet container, and may be specified + * in a web application deployment descriptor. Common MIME + * types are "text/html" and "image/gif". + * + * @param file a String specifying the name + * of a file + * + * @return a String specifying the file's MIME type + */ + public String getMimeType(String file) { + return "text/html"; + } + + /** + * Returns a directory-like listing of all the paths to resources within + * the web application whose longest sub-path matches the supplied path + * argument. Paths indicating subdirectory paths end with a '/'. The + * returned paths are all relative to the root of the web application and + * have a leading '/'. For example, for a web application containing
+ *
+ * /welcome.html
+ * /catalog/index.html
+ * /catalog/products.html
+ * /catalog/offers/books.html
+ * /catalog/offers/music.html
+ * /customer/login.jsp
+ * /WEB-INF/web.xml
+ * /WEB-INF/classes/com.acme.OrderServlet.class,

+ * + * getResourcePaths("/") returns {"/welcome.html", "/catalog/", "/customer/", "/WEB-INF/"}
+ * getResourcePaths("/catalog/") returns {"/catalog/index.html", "/catalog/products.html", "/catalog/offers/"}.
+ * + * @param path the partial path used to match the resources, + * which must start with a / + * @return a Set containing the directory listing, or null if there are no + * resources in the web application whose path begins with the supplied path. + * + * @since Servlet 2.3 + */ + public Set getResourcePaths(String path) { + return null; + } + + /** + * Returns a URL to the resource that is mapped to a specified + * path. The path must begin with a "/" and is interpreted + * as relative to the current context root. + * + *

This method allows the servlet container to make a resource + * available to servlets from any source. Resources + * can be located on a local or remote + * file system, in a database, or in a .war file. + * + *

The servlet container must implement the URL handlers + * and URLConnection objects that are necessary + * to access the resource. + * + *

This method returns null + * if no resource is mapped to the pathname. + * + *

Some containers may allow writing to the URL returned by + * this method using the methods of the URL class. + * + *

The resource content is returned directly, so be aware that + * requesting a .jsp page returns the JSP source code. + * Use a RequestDispatcher instead to include results of + * an execution. + * + *

This method has a different purpose than + * java.lang.Class.getResource, + * which looks up resources based on a class loader. This + * method does not use class loaders. + * + * @param path a String specifying the path to the resource + * + * @return the resource located at the named path, or null + * if there is no resource at that path + * + * @exception MalformedURLException if the pathname is not given in + * the correct form + */ + public URL getResource(String path) throws MalformedURLException { + return null; + } + + /** + * Returns the resource located at the named path as + * an InputStream object. + * + *

The data in the InputStream can be + * of any type or length. The path must be specified according + * to the rules given in getResource. + * This method returns null if no resource exists at + * the specified path. + * + *

Meta-information such as content length and content type + * that is available via getResource + * method is lost when using this method. + * + *

The servlet container must implement the URL handlers + * and URLConnection objects necessary to access + * the resource. + * + *

This method is different from + * java.lang.Class.getResourceAsStream, + * which uses a class loader. This method allows servlet containers + * to make a resource available + * to a servlet from any location, without using a class loader. + * + * @param path a String specifying the path + * to the resource + * + * @return the InputStream returned to the + * servlet, or null if no resource exists at the + * specified path + */ + public InputStream getResourceAsStream(String path) { + return null; + } + + /** + * Returns a {@link RequestDispatcher} object that acts + * as a wrapper for the resource located at the given path. + * A RequestDispatcher object can be used to forward + * a request to the resource or to include the resource in a response. + * The resource can be dynamic or static. + * + *

The pathname must begin with a "/" and is interpreted as relative + * to the current context root. Use getContext to obtain + * a RequestDispatcher for resources in foreign contexts. + * This method returns null if the ServletContext + * cannot return a RequestDispatcher. + * + * @param path a String specifying the pathname + * to the resource + * + * @return a RequestDispatcher object that acts as a wrapper + * for the resource at the specified path, or null if the + * ServletContext cannot return a RequestDispatcher + * + * @see RequestDispatcher + * @see ServletContext#getContext + */ + public RequestDispatcher getRequestDispatcher(String path) { + return null; + } + + /** + * Returns a {@link RequestDispatcher} object that acts + * as a wrapper for the named servlet. + * + *

Servlets (and JSP pages also) may be given names via server + * administration or via a web application deployment descriptor. + * A servlet instance can determine its name using + * {@link ServletConfig#getServletName}. + * + *

This method returns null if the + * ServletContext + * cannot return a RequestDispatcher for any reason. + * + * @param name a String specifying the name + * of a servlet to wrap + * + * @return a RequestDispatcher object + * that acts as a wrapper for the named servlet, + * or null if the ServletContext + * cannot return a RequestDispatcher + * + * @see RequestDispatcher + * @see ServletContext#getContext + * @see ServletConfig#getServletName + */ + public RequestDispatcher getNamedDispatcher(String name) { + return null; + } + + /** + * @deprecated As of Java Servlet API 2.1, with no direct replacement. + * + *

This method was originally defined to retrieve a servlet + * from a ServletContext. In this version, this method + * always returns null and remains only to preserve + * binary compatibility. This method will be permanently removed + * in a future version of the Java Servlet API. + * + *

In lieu of this method, servlets can share information using the + * ServletContext class and can perform shared business logic + * by invoking methods on common non-servlet classes. + */ + @Deprecated + public Servlet getServlet(String name) throws ServletException { + return null; + } + + /** + * @deprecated As of Java Servlet API 2.0, with no replacement. + * + *

This method was originally defined to return an Enumeration + * of all the servlets known to this servlet context. In this + * version, this method always returns an empty enumeration and + * remains only to preserve binary compatibility. This method + * will be permanently removed in a future version of the Java + * Servlet API. + */ + @Deprecated + public Enumeration getServlets() { + return null; + } + + /** + * @deprecated As of Java Servlet API 2.1, with no replacement. + * + *

This method was originally defined to return an + * Enumeration + * of all the servlet names known to this context. In this version, + * this method always returns an empty Enumeration and + * remains only to preserve binary compatibility. This method will + * be permanently removed in a future version of the Java Servlet API. + */ + @Deprecated + public Enumeration getServletNames() { + return null; + } + + /** + * Writes the specified message to a servlet log file, usually + * an event log. The name and type of the servlet log file is + * specific to the servlet container. + * + * @param msg a String specifying the + * message to be written to the log file + */ + public void log(String msg) { + ESAPI.getLogger( "MockServletContext" ).warning( Logger.EVENT_FAILURE, msg ); + } + + /** + * @deprecated As of Java Servlet API 2.1, use + * {@link #log(String message, Throwable throwable)} + * instead. + * + *

This method was originally defined to write an + * exception's stack trace and an explanatory error message + * to the servlet log file. + */ + @Deprecated + public void log(Exception exception, String msg) { + ESAPI.getLogger( "MockServletContext" ).warning( Logger.EVENT_FAILURE, msg, exception ); + } + + /** + * Writes an explanatory message and a stack trace + * for a given Throwable exception + * to the servlet log file. The name and type of the servlet log + * file is specific to the servlet container, usually an event log. + * + * @param message a String that + * describes the error or exception + * + * @param throwable the Throwable error + * or exception + */ + public void log(String message, Throwable throwable) { + ESAPI.getLogger( "MockServletContext" ).warning( Logger.EVENT_FAILURE, message, throwable ); + } + + /** + * Returns a String containing the real path + * for a given virtual path. For example, the path "/index.html" + * returns the absolute file path on the server's filesystem would be + * served by a request for "http://host/contextPath/index.html", + * where contextPath is the context path of this ServletContext.. + * + *

The real path returned will be in a form + * appropriate to the computer and operating system on + * which the servlet container is running, including the + * proper path separators. This method returns null + * if the servlet container cannot translate the virtual path + * to a real path for any reason (such as when the content is + * being made available from a .war archive). + * + * @param path a String specifying a virtual path + * + * @return a String specifying the real path, + * or null if the translation cannot be performed + */ + public String getRealPath(String path) { + return ESAPI.securityConfiguration().getResourceFile( path ).getAbsolutePath(); + } + + /** + * Returns the name and version of the servlet container on which + * the servlet is running. + * + *

The form of the returned string is + * servername/versionnumber. + * For example, the JavaServer Web Development Kit may return the string + * JavaServer Web Dev Kit/1.0. + * + *

The servlet container may return other optional information + * after the primary string in parentheses, for example, + * JavaServer Web Dev Kit/1.0 (JDK 1.1.6; Windows NT 4.0 x86). + * + * @return a String containing at least the + * servlet container name and version number + */ + public String getServerInfo() { + return null; + } + + /** + * Returns a String containing the value of the named + * context-wide initialization parameter, or null if the + * parameter does not exist. + * + *

This method can make available configuration information useful + * to an entire "web application". For example, it can provide a + * webmaster's email address or the name of a system that holds + * critical data. + * + * @param name a String containing the name of the + * parameter whose value is requested + * + * @return a String containing at least the + * servlet container name and version number + * + * @see ServletConfig#getInitParameter + */ + public String getInitParameter(String name) { + return null; + } + + /** + * Returns the names of the context's initialization parameters as an + * Enumeration of String objects, or an + * empty Enumeration if the context has no initialization + * parameters. + * + * @return an Enumeration of String + * objects containing the names of the context's initialization parameters + * + * @see ServletConfig#getInitParameter + */ + public Enumeration getInitParameterNames() { + return null; + } + + + /** + * Returns the servlet container attribute with the given name, + * or null if there is no attribute by that name. + * An attribute allows a servlet container to give the + * servlet additional information not + * already provided by this interface. See your + * server documentation for information about its attributes. + * A list of supported attributes can be retrieved using + * getAttributeNames. + * + *

The attribute is returned as a java.lang.Object + * or some subclass. + * Attribute names should follow the same convention as package + * names. The Java Servlet API specification reserves names + * matching java.*, javax.*, + * and sun.*. + * + * @param name a String specifying the name + * of the attribute + * + * @return an Object containing the value + * of the attribute, or null if no attribute + * exists matching the given name + * + * @see ServletContext#getAttributeNames + */ + public Object getAttribute(String name) { + return null; + } + + /** + * Returns an Enumeration containing the + * attribute names available + * within this servlet context. Use the + * {@link #getAttribute} method with an attribute name + * to get the value of an attribute. + * + * @return an Enumeration of attribute names + * + * @see #getAttribute + */ + public Enumeration getAttributeNames() { + return null; + } + + /** + * Binds an object to a given attribute name in this servlet context. If + * the name specified is already used for an attribute, this + * method will replace the attribute with the new to the new attribute. + *

If listeners are configured on the ServletContext the + * container notifies them accordingly. + *

+ * If a null value is passed, the effect is the same as calling + * removeAttribute(). + * + *

Attribute names should follow the same convention as package + * names. The Java Servlet API specification reserves names + * matching java.*, javax.*, and + * sun.*. + * + * @param name a String specifying the name + * of the attribute + * + * @param object an Object representing the + * attribute to be bound + */ + public void setAttribute(String name, Object object) { + } + + /** + * Removes the attribute with the given name from + * the servlet context. After removal, subsequent calls to + * {@link #getAttribute} to retrieve the attribute's value + * will return null. + * + *

If listeners are configured on the ServletContext the + * container notifies them accordingly. + * + * @param name a String specifying the name + * of the attribute to be removed + */ + public void removeAttribute(String name) { + } + + /** + * Returns the name of this web application correponding to this ServletContext as specified in the deployment + * descriptor for this web application by the display-name element. + * + * @return The name of the web application or null if no name has been declared in the deployment descriptor. + * @since Servlet 2.3 + */ + public String getServletContextName() { + return null; + } + + @Override + public int getEffectiveMajorVersion() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public int getEffectiveMinorVersion() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public boolean setInitParameter(String string, String string1) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public ServletRegistration.Dynamic addServlet(String string, String string1) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public ServletRegistration.Dynamic addServlet(String string, Servlet srvlt) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public ServletRegistration.Dynamic addServlet(String string, Class type) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public T createServlet(Class type) throws ServletException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public ServletRegistration getServletRegistration(String string) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public Map getServletRegistrations() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public FilterRegistration.Dynamic addFilter(String string, String string1) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public FilterRegistration.Dynamic addFilter(String string, Filter filter) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public FilterRegistration.Dynamic addFilter(String string, Class type) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public T createFilter(Class type) throws ServletException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public FilterRegistration getFilterRegistration(String string) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public Map getFilterRegistrations() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public SessionCookieConfig getSessionCookieConfig() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void setSessionTrackingModes(Set set) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public Set getDefaultSessionTrackingModes() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public Set getEffectiveSessionTrackingModes() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void addListener(String string) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void addListener(T t) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void addListener(Class type) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public T createListener(Class type) throws ServletException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public JspConfigDescriptor getJspConfigDescriptor() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public ClassLoader getClassLoader() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void declareRoles(String... strings) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public String getVirtualServerName() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } +} \ No newline at end of file diff --git a/src/test/java/org/owasp/esapi/http/MockServletInputStream.java b/src/test/java/org/owasp/esapi/http/MockServletInputStream.java new file mode 100644 index 000000000..f54b49144 --- /dev/null +++ b/src/test/java/org/owasp/esapi/http/MockServletInputStream.java @@ -0,0 +1,69 @@ +/** + * 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.http; + +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import java.io.IOException; + +/** + * + * @author jwilliams + */ +public class MockServletInputStream extends ServletInputStream { + + private byte[] body; + + private int next; + + private boolean isDone = false; + /** + * constructor + * @param body + */ + public MockServletInputStream(byte[] body) { + this.body = body; + } + + /** + * read + * @return the next char from this InputStream + * @throws IOException + */ + public int read() throws IOException { + if (next < body.length) { + return body[next++]; + } else { + isDone = true; + return -1; + } + } + + @Override + public boolean isFinished() { + return isDone; + } + + @Override + public boolean isReady() { + return false; + } + + @Override + public void setReadListener(ReadListener readListener) { + //NO_OP + } +} diff --git a/src/test/java/org/owasp/esapi/http/package.html b/src/test/java/org/owasp/esapi/http/package.html new file mode 100644 index 000000000..c61efd69f --- /dev/null +++ b/src/test/java/org/owasp/esapi/http/package.html @@ -0,0 +1,15 @@ + + + + + + + +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. + + + diff --git a/src/test/java/org/owasp/esapi/logging/appender/ClientInfoSupplierTest.java b/src/test/java/org/owasp/esapi/logging/appender/ClientInfoSupplierTest.java new file mode 100644 index 000000000..e3dcd76a5 --- /dev/null +++ b/src/test/java/org/owasp/esapi/logging/appender/ClientInfoSupplierTest.java @@ -0,0 +1,168 @@ +package org.owasp.esapi.logging.appender; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.when; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestName; +import org.junit.runner.RunWith; +import org.mockito.ArgumentMatchers; +import org.owasp.esapi.Authenticator; +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Randomizer; +import org.owasp.esapi.User; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ESAPI.class}) +@PowerMockIgnore("javax.security.*") //Required since User extends javax.security.Principal +public class ClientInfoSupplierTest { + private static final String ESAPI_SESSION_ATTR = "ESAPI_SESSION"; + + @Rule + public TestName testName = new TestName(); + + private HttpServletRequest mockRequest; + private HttpSession mockSession; + private Authenticator mockAuth; + private Randomizer mockRand; + private User mockUser; + + @Before + public void before() throws Exception { + mockAuth =mock(Authenticator.class); + mockRand =mock(Randomizer.class); + mockRequest =mock(HttpServletRequest.class); + mockSession =mock(HttpSession.class); + mockUser =mock(User.class); + + mockStatic(ESAPI.class); + when(ESAPI.class, "currentRequest").thenReturn(mockRequest); + when(ESAPI.class, "authenticator").thenReturn(mockAuth); + when(ESAPI.class, "randomizer").thenReturn(mockRand); + + when(mockRequest.getSession(false)).thenReturn(mockSession); + when(mockSession.getAttribute(ESAPI_SESSION_ATTR)).thenReturn(testName.getMethodName()+ "-SESSION"); + + //Session value generation + when(mockRand.getRandomInteger(ArgumentMatchers.anyInt(), ArgumentMatchers.anyInt())).thenReturn(55555); + + when(mockUser.getLastHostAddress()).thenReturn(testName.getMethodName() + "-HOST_ADDR"); + + + when(mockAuth.getCurrentUser()).thenReturn(mockUser); + } + + @Test + public void testHappyPath() throws Exception { + ClientInfoSupplier cis = new ClientInfoSupplier(); + cis.setLogClientInfo(true); + String result = cis.get(); + + assertEquals(testName.getMethodName() + "-SESSION@"+testName.getMethodName() + "-HOST_ADDR", result); + + verify(mockAuth,times(1)).getCurrentUser(); + verify(mockRequest,times(1)).getSession(false); + verify(mockSession,times(1)).getAttribute(ESAPI_SESSION_ATTR); + verify(mockUser,times(1)).getLastHostAddress(); + + verifyNoMoreInteractions(mockAuth, mockRand, mockRequest, mockSession, mockUser); + } + + @Test + public void testLogUserOff() { + ClientInfoSupplier cis = new ClientInfoSupplier(); + cis.setLogClientInfo(false); + String result = cis.get(); + + assertTrue(result.isEmpty()); + + verifyNoMoreInteractions(mockAuth, mockRand, mockRequest, mockSession, mockUser); + } + + @Test + public void testLogUserNull() { + when(mockAuth.getCurrentUser()).thenReturn(null); + ClientInfoSupplier cis = new ClientInfoSupplier(); + cis.setLogClientInfo(true); + String result = cis.get(); + + assertEquals(testName.getMethodName()+ "-SESSION@#UNKNOWN_HOST#", result); + + verify(mockAuth,times(1)).getCurrentUser(); + verify(mockRequest,times(1)).getSession(false); + verify(mockSession,times(1)).getAttribute(ESAPI_SESSION_ATTR); + + verifyNoMoreInteractions(mockAuth, mockRand, mockRequest, mockSession, mockUser); + } + + @Test + public void testNullRequest() throws Exception { + when(ESAPI.class, "currentRequest").thenReturn(null); + ClientInfoSupplier cis = new ClientInfoSupplier(); + cis.setLogClientInfo(true); + String result = cis.get(); + + //sid is empty when request is null + assertEquals("@"+testName.getMethodName() + "-HOST_ADDR", result); + + verify(mockAuth,times(1)).getCurrentUser(); + verify(mockUser,times(1)).getLastHostAddress(); + + verifyNoMoreInteractions(mockAuth, mockRand, mockRequest, mockSession, mockUser); + } + + @Test + public void testNullSession() throws Exception { + when(mockRequest.getSession(false)).thenReturn(null); + ClientInfoSupplier cis = new ClientInfoSupplier(); + cis.setLogClientInfo(true); + String result = cis.get(); + + //sid is empty when session is null + assertEquals("@"+testName.getMethodName() + "-HOST_ADDR", result); + + + verify(mockAuth,times(1)).getCurrentUser(); + verify(mockRequest,times(1)).getSession(false); + verify(mockUser,times(1)).getLastHostAddress(); + + + verifyNoMoreInteractions(mockAuth, mockRand, mockRequest, mockSession, mockUser); + } + + + + @Test + public void testNullEsapiSession() throws Exception { + when(mockSession.getAttribute(ESAPI_SESSION_ATTR)).thenReturn(null); + ClientInfoSupplier cis = new ClientInfoSupplier(); + cis.setLogClientInfo(true); + String result = cis.get(); + + //sid is empty when session is null + assertEquals("55555@"+testName.getMethodName() + "-HOST_ADDR", result); + + verify(mockAuth,times(1)).getCurrentUser(); + verify(mockRequest,times(1)).getSession(false); + verify(mockSession,times(1)).getAttribute(ESAPI_SESSION_ATTR); + verify(mockSession, times(1)).setAttribute(ESAPI_SESSION_ATTR, (""+55555)); + verify(mockRand, times(1)).getRandomInteger(ArgumentMatchers.anyInt(), ArgumentMatchers.anyInt()); + verify(mockUser,times(1)).getLastHostAddress(); + + verifyNoMoreInteractions(mockAuth, mockRand, mockRequest, mockSession, mockUser); + } +} \ No newline at end of file diff --git a/src/test/java/org/owasp/esapi/logging/appender/EventTypeLogSupplierIgnoreEventTypeTest.java b/src/test/java/org/owasp/esapi/logging/appender/EventTypeLogSupplierIgnoreEventTypeTest.java new file mode 100644 index 000000000..3f8858bfa --- /dev/null +++ b/src/test/java/org/owasp/esapi/logging/appender/EventTypeLogSupplierIgnoreEventTypeTest.java @@ -0,0 +1,45 @@ +package org.owasp.esapi.logging.appender; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.owasp.esapi.Logger; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@RunWith(Parameterized.class) +public class EventTypeLogSupplierIgnoreEventTypeTest { + + @Parameterized.Parameters (name="{0} -> {1}") + public static Collection assembleTests() { + List paramSets = new ArrayList<>(); + paramSets.add(new Object[] {Logger.EVENT_FAILURE,""}); + paramSets.add(new Object[] {Logger.EVENT_SUCCESS,""}); + paramSets.add(new Object[] {Logger.EVENT_UNSPECIFIED,""}); + paramSets.add(new Object[] {Logger.SECURITY_AUDIT,""}); + paramSets.add(new Object[] {Logger.SECURITY_FAILURE,""}); + paramSets.add(new Object[] {Logger.SECURITY_SUCCESS,""}); + paramSets.add(new Object[] {null, ""}); + + return paramSets; + } + + private final Logger.EventType eventType; + private final String expectedResult; + + public EventTypeLogSupplierIgnoreEventTypeTest(Logger.EventType eventType, String result) { + this.eventType = eventType; + this.expectedResult = result; + } + + @Test + public void testEventTypeLogIgnoreEventType() { + EventTypeLogSupplier supplier = new EventTypeLogSupplier(eventType); + supplier.setLogEventType(false); + assertEquals(expectedResult, supplier.get()); + } +} diff --git a/src/test/java/org/owasp/esapi/logging/appender/EventTypeLogSupplierTest.java b/src/test/java/org/owasp/esapi/logging/appender/EventTypeLogSupplierTest.java new file mode 100644 index 000000000..f547ce61c --- /dev/null +++ b/src/test/java/org/owasp/esapi/logging/appender/EventTypeLogSupplierTest.java @@ -0,0 +1,46 @@ +package org.owasp.esapi.logging.appender; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; +import org.owasp.esapi.Logger; +import org.owasp.esapi.Logger.EventType; + +@RunWith(Parameterized.class) +public class EventTypeLogSupplierTest { + + @Parameters (name="{0} -> {1}") + public static Collection assembleTests() { + List paramSets = new ArrayList<>(); + paramSets.add(new Object[] {Logger.EVENT_FAILURE,Logger.EVENT_FAILURE.toString()}); + paramSets.add(new Object[] {Logger.EVENT_SUCCESS,Logger.EVENT_SUCCESS.toString()}); + paramSets.add(new Object[] {Logger.EVENT_UNSPECIFIED,Logger.EVENT_UNSPECIFIED.toString()}); + paramSets.add(new Object[] {Logger.SECURITY_AUDIT,Logger.SECURITY_AUDIT.toString()}); + paramSets.add(new Object[] {Logger.SECURITY_FAILURE,Logger.SECURITY_FAILURE.toString()}); + paramSets.add(new Object[] {Logger.SECURITY_SUCCESS,Logger.SECURITY_SUCCESS.toString()}); + paramSets.add(new Object[] {null, Logger.EVENT_UNSPECIFIED.toString()}); + + return paramSets; + } + + private final EventType eventType; + private final String expectedResult; + + public EventTypeLogSupplierTest(EventType eventType, String result) { + this.eventType = eventType; + this.expectedResult = result; + } + @Test + public void testEventTypeLog() { + EventTypeLogSupplier supplier = new EventTypeLogSupplier(eventType); + assertEquals(expectedResult, supplier.get()); + } + +} diff --git a/src/test/java/org/owasp/esapi/logging/appender/LogPrefixAppenderTest.java b/src/test/java/org/owasp/esapi/logging/appender/LogPrefixAppenderTest.java new file mode 100644 index 000000000..cbd368b5e --- /dev/null +++ b/src/test/java/org/owasp/esapi/logging/appender/LogPrefixAppenderTest.java @@ -0,0 +1,218 @@ +package org.owasp.esapi.logging.appender; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.powermock.api.mockito.PowerMockito.whenNew; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestName; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.owasp.esapi.Logger; +import org.owasp.esapi.Logger.EventType; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +@RunWith(PowerMockRunner.class) +@PrepareForTest(LogPrefixAppender.class) +public class LogPrefixAppenderTest { + private static final String EMPTY_RESULT = " "; + private static final String ETL_RESULT = "EVENT_TYPE"; + private static final String CIS_RESULT = "CLIENT_INFO"; + private static final String UIS_RESULT = "USER_INFO"; + private static final String SIS_RESULT = "SERVER_INFO"; + + @Rule + public TestName testName = new TestName(); + + private String testLoggerName = testName.getMethodName() + "-LOGGER"; + private String testLogMessage = testName.getMethodName() + "-MESSAGE"; + private String testApplicationName = testName.getMethodName() + "-APPLICATION_NAME"; + private EventType testEventType = Logger.EVENT_UNSPECIFIED; + + private EventTypeLogSupplier etlsSpy; + private ClientInfoSupplier cisSpy; + private UserInfoSupplier uisSpy; + private ServerInfoSupplier sisSpy; + + @Before + public void buildSupplierSpies() { + etlsSpy = spy(new EventTypeLogSupplier(Logger.EVENT_UNSPECIFIED)); + uisSpy = spy(new UserInfoSupplier()); + cisSpy = spy(new ClientInfoSupplier()); + sisSpy = spy(new ServerInfoSupplier(testName.getMethodName())); + + testLoggerName = testName.getMethodName() + "-LOGGER"; + testLogMessage = testName.getMethodName() + "-MESSAGE"; + testApplicationName = testName.getMethodName() + "-APPLICATION_NAME"; + } + @Test + public void testCtrArgTruePassthroughToDelegates() throws Exception { + when(etlsSpy.get()).thenReturn(ETL_RESULT); + when(uisSpy.get()).thenReturn(UIS_RESULT); + when(cisSpy.get()).thenReturn(CIS_RESULT); + when(sisSpy.get()).thenReturn(SIS_RESULT); + + whenNew(EventTypeLogSupplier.class).withArguments(testEventType).thenReturn(etlsSpy); + whenNew(UserInfoSupplier.class).withNoArguments().thenReturn(uisSpy); + whenNew(ClientInfoSupplier.class).withNoArguments().thenReturn(cisSpy); + whenNew(ServerInfoSupplier.class).withArguments(testLoggerName).thenReturn(sisSpy); + + LogPrefixAppender lpa = new LogPrefixAppender(true, true,true,true, testApplicationName); + lpa.appendTo(testLoggerName, testEventType, testLogMessage); + + verify(uisSpy, times(1)).setLogUserInfo(true); + verify(cisSpy, times(1)).setLogClientInfo(true); + verify(sisSpy, times(1)).setLogServerIp(true); + verify(sisSpy, times(1)).setLogApplicationName(true, testApplicationName); + } + + @Test + public void testCtrArgFalsePassthroughToDelegates() throws Exception { + when(etlsSpy.get()).thenReturn(ETL_RESULT); + when(uisSpy.get()).thenReturn(UIS_RESULT); + when(cisSpy.get()).thenReturn(CIS_RESULT); + when(sisSpy.get()).thenReturn(SIS_RESULT); + + whenNew(EventTypeLogSupplier.class).withArguments(testEventType).thenReturn(etlsSpy); + whenNew(UserInfoSupplier.class).withNoArguments().thenReturn(uisSpy); + whenNew(ClientInfoSupplier.class).withNoArguments().thenReturn(cisSpy); + whenNew(ServerInfoSupplier.class).withArguments(testLoggerName).thenReturn(sisSpy); + + LogPrefixAppender lpa = new LogPrefixAppender(false, false, false, false, null); + lpa.appendTo(testLoggerName, testEventType, testLogMessage); + + verify(uisSpy, times(1)).setLogUserInfo(false); + verify(cisSpy, times(1)).setLogClientInfo(false); + verify(sisSpy, times(1)).setLogServerIp(false); + verify(sisSpy, times(1)).setLogApplicationName(false, null); + } + + @Test + public void testDelegateCtrArgs() throws Exception { + ArgumentCaptor eventTypeCapture = ArgumentCaptor.forClass(EventType.class); + ArgumentCaptor logNameCapture = ArgumentCaptor.forClass(String.class); + whenNew(EventTypeLogSupplier.class).withArguments(eventTypeCapture.capture()).thenReturn(etlsSpy); + whenNew(UserInfoSupplier.class).withNoArguments().thenReturn(uisSpy); + whenNew(ClientInfoSupplier.class).withNoArguments().thenReturn(cisSpy); + whenNew(ServerInfoSupplier.class).withArguments(logNameCapture.capture()).thenReturn(sisSpy); + + LogPrefixAppender lpa = new LogPrefixAppender(true, true,true,true, testApplicationName); + lpa.appendTo(testLoggerName, testEventType, testLogMessage); + + assertEquals(testEventType, eventTypeCapture.getValue()); + assertEquals(testLoggerName, logNameCapture.getValue()); + } + + @Test + public void testLogContentWhenClientInfoEmpty() throws Exception { + runTest(ETL_RESULT, UIS_RESULT, EMPTY_RESULT,SIS_RESULT, "[EVENT_TYPE USER_INFO -> SERVER_INFO]"); + } + + + @Test + public void testLogContentWhenUserInfoEmpty() throws Exception { + runTest(ETL_RESULT, EMPTY_RESULT, CIS_RESULT,SIS_RESULT, "[EVENT_TYPE CLIENT_INFO -> SERVER_INFO]"); + } + + @Test + public void testLogContentWhenClientInfoEmptyAndServerInfoEmpty() throws Exception { + runTest(ETL_RESULT, UIS_RESULT, EMPTY_RESULT,EMPTY_RESULT, "[EVENT_TYPE USER_INFO]"); + } + + @Test + public void testLogContentWhenUserInfoEmptyAndServerInfoEmpty() throws Exception { + runTest(ETL_RESULT, EMPTY_RESULT, CIS_RESULT,EMPTY_RESULT, "[EVENT_TYPE CLIENT_INFO]"); + } + + @Test + public void testLogContentWhenUserInfoAndClientInfoEmpty() throws Exception { + runTest(ETL_RESULT, EMPTY_RESULT, EMPTY_RESULT, SIS_RESULT, "[EVENT_TYPE -> SERVER_INFO]"); + } + + @Test + public void testLogContentWhenServerInfoEmpty() throws Exception { + runTest(ETL_RESULT, UIS_RESULT, CIS_RESULT, EMPTY_RESULT, "[EVENT_TYPE USER_INFO:CLIENT_INFO]"); + } + + @Test + public void testLogContentWhenUserInfoEmptyAndClientInfoEmptyAndServerInfoEmpty() throws Exception { + runTest(ETL_RESULT, EMPTY_RESULT, EMPTY_RESULT, EMPTY_RESULT, "[EVENT_TYPE]"); + } + + private void runTest(String typeResult, String userResult, String clientResult, String serverResult, String exResult) throws Exception{ + when(etlsSpy.get()).thenReturn(typeResult); + when(uisSpy.get()).thenReturn(userResult); + when(cisSpy.get()).thenReturn(clientResult); + when(sisSpy.get()).thenReturn(serverResult); + + whenNew(EventTypeLogSupplier.class).withArguments(testEventType).thenReturn(etlsSpy); + whenNew(UserInfoSupplier.class).withNoArguments().thenReturn(uisSpy); + whenNew(ClientInfoSupplier.class).withNoArguments().thenReturn(cisSpy); + whenNew(ServerInfoSupplier.class).withArguments(testLoggerName).thenReturn(sisSpy); + + //Since everything is mocked these booleans don't much matter aside from the later verifies + LogPrefixAppender lpa = new LogPrefixAppender(false, false, false, false, null); + String result = lpa.appendTo(testLoggerName, testEventType, testLogMessage); + + assertEquals(exResult + " " + testName.getMethodName() + "-MESSAGE", result); + } + + @Test + public void testLogContentWhenServerInfoEmptyAndIgnoreLogPrefix() throws Exception { + runTestWithLogPrefixIgnore(ETL_RESULT, UIS_RESULT, CIS_RESULT, EMPTY_RESULT, false, "[ USER_INFO:CLIENT_INFO]"); + } + + @Test + public void testLogContentWhenUserInfoEmptyAndServerInfoEmptyAndIgnoreLogPrefix() throws Exception { + runTestWithLogPrefixIgnore(ETL_RESULT, EMPTY_RESULT, CIS_RESULT, EMPTY_RESULT, false, "[ CLIENT_INFO]"); + } + + @Test + public void testLogContentWhenUserInfoEmptyAndClientInfoEmptyAndIgnoreLogPrefix() throws Exception { + runTestWithLogPrefixIgnore(ETL_RESULT, EMPTY_RESULT, EMPTY_RESULT, SIS_RESULT, false, "[ -> SERVER_INFO]"); + } + + @Test + public void testLogContentWhenClientInfoEmptyAndServerInfoEmptyAndIgnoreLogPrefix() throws Exception { + runTestWithLogPrefixIgnore(ETL_RESULT, UIS_RESULT, EMPTY_RESULT, EMPTY_RESULT, false, "[ USER_INFO]"); + } + + @Test + public void testLogContentWhenUserInfoEmptyAndClientInfoEmptyAndServerInfoEmptyAndIgnoreLogPrefix() throws Exception { + runTestWithLogPrefixIgnore(ETL_RESULT, EMPTY_RESULT, EMPTY_RESULT, EMPTY_RESULT, false, ""); + } + + private void runTestWithLogPrefixIgnore(String typeResult, String userResult, String clientResult, String serverResult, boolean logPrefix, String exResult) throws Exception{ + etlsSpy.setLogEventType(logPrefix); + when(etlsSpy.get()).thenReturn(typeResult); + + when(uisSpy.get()).thenReturn(userResult); + when(cisSpy.get()).thenReturn(clientResult); + + sisSpy.setLogLogName(logPrefix); + when(sisSpy.get()).thenReturn(serverResult); + + whenNew(EventTypeLogSupplier.class).withArguments(testEventType).thenReturn(etlsSpy); + whenNew(UserInfoSupplier.class).withNoArguments().thenReturn(uisSpy); + whenNew(ClientInfoSupplier.class).withNoArguments().thenReturn(cisSpy); + whenNew(ServerInfoSupplier.class).withArguments(testLoggerName).thenReturn(sisSpy); + + //Since everything is mocked these booleans don't much matter aside from the later verifies + LogPrefixAppender lpa = new LogPrefixAppender(false, false, false, false, null, false); + String result = lpa.appendTo(testLoggerName, testEventType, testLogMessage); + + if (exResult.isEmpty()) { + assertEquals( testName.getMethodName() + "-MESSAGE", result); + } + else { + assertEquals(exResult + " " + testName.getMethodName() + "-MESSAGE", result); + } + } + +} diff --git a/src/test/java/org/owasp/esapi/logging/appender/ServerInfoSupplierIgnoreLogNameTest.java b/src/test/java/org/owasp/esapi/logging/appender/ServerInfoSupplierIgnoreLogNameTest.java new file mode 100644 index 000000000..5bd3c8335 --- /dev/null +++ b/src/test/java/org/owasp/esapi/logging/appender/ServerInfoSupplierIgnoreLogNameTest.java @@ -0,0 +1,116 @@ +package org.owasp.esapi.logging.appender; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.when; + +import javax.servlet.http.HttpServletRequest; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestName; +import org.junit.runner.RunWith; +import org.owasp.esapi.ESAPI; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ ESAPI.class }) +public class ServerInfoSupplierIgnoreLogNameTest { + @Rule + public TestName testName = new TestName(); + + private HttpServletRequest request; + + @Before + public void buildStaticMocks() { + request = mock(HttpServletRequest.class); + mockStatic(ESAPI.class); + } + + @Test + public void verifyFullOutputIgnoreLogName() throws Exception { + when(ESAPI.class, "currentRequest").thenReturn(request); + when(request.getLocalAddr()).thenReturn("LOCAL_ADDR"); + when(request.getLocalPort()).thenReturn(99999); + + ServerInfoSupplier sis = new ServerInfoSupplier(testName.getMethodName()); + sis.setLogApplicationName(true, testName.getMethodName() + "-APPLICATION"); + sis.setLogServerIp(true); + sis.setLogLogName(false); + + String result = sis.get(); + assertEquals("LOCAL_ADDR:99999/" + testName.getMethodName() + "-APPLICATION", + result); + } + + @Test + public void verifyOutputNullRequestIgnoreLogName() throws Exception { + when(ESAPI.class, "currentRequest").thenReturn(null); + ServerInfoSupplier sis = new ServerInfoSupplier(testName.getMethodName()); + sis.setLogApplicationName(true, testName.getMethodName() + "-APPLICATION"); + sis.setLogServerIp(true); + sis.setLogLogName(false); + + String result = sis.get(); + assertEquals("/" + testName.getMethodName() + "-APPLICATION", result); + } + + @Test + public void verifyOutputNoAppNameIgnoreLogName() throws Exception { + when(ESAPI.class, "currentRequest").thenReturn(request); + when(request.getLocalAddr()).thenReturn("LOCAL_ADDR"); + when(request.getLocalPort()).thenReturn(99999); + + ServerInfoSupplier sis = new ServerInfoSupplier(testName.getMethodName()); + sis.setLogApplicationName(false, null); + sis.setLogServerIp(true); + sis.setLogLogName(false); + + String result = sis.get(); + assertEquals("LOCAL_ADDR:99999", result); + } + + @Test + public void verifyOutputNullAppNameIgnoreLogName() throws Exception { + when(ESAPI.class, "currentRequest").thenReturn(request); + when(request.getLocalAddr()).thenReturn("LOCAL_ADDR"); + when(request.getLocalPort()).thenReturn(99999); + + ServerInfoSupplier sis = new ServerInfoSupplier(testName.getMethodName()); + sis.setLogApplicationName(true, null); + sis.setLogServerIp(true); + sis.setLogLogName(false); + + String result = sis.get(); + assertEquals("LOCAL_ADDR:99999/null", result); + } + + @Test + public void verifyOutputNoServerIpIgnoreLogName() { + ServerInfoSupplier sis = new ServerInfoSupplier(testName.getMethodName()); + sis.setLogApplicationName(true, testName.getMethodName() + "-APPLICATION"); + sis.setLogServerIp(false); + sis.setLogLogName(false); + + String result = sis.get(); + assertEquals("/" + testName.getMethodName() + "-APPLICATION", result); + } + + @Test + public void verifyOutputNullRequestNoServerIpNullAppNameIgnoreLogName() throws Exception { + when(ESAPI.class, "currentRequest").thenReturn(null); + ServerInfoSupplier sis = new ServerInfoSupplier(testName.getMethodName()); + sis.setLogApplicationName(false, null); + sis.setLogServerIp(false); + sis.setLogLogName(false); + + String result = sis.get(); + assertEquals("", result); + } + + +} + diff --git a/src/test/java/org/owasp/esapi/logging/appender/ServerInfoSupplierTest.java b/src/test/java/org/owasp/esapi/logging/appender/ServerInfoSupplierTest.java new file mode 100644 index 000000000..807c61290 --- /dev/null +++ b/src/test/java/org/owasp/esapi/logging/appender/ServerInfoSupplierTest.java @@ -0,0 +1,97 @@ +package org.owasp.esapi.logging.appender; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.when; + +import javax.servlet.http.HttpServletRequest; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestName; +import org.junit.runner.RunWith; +import org.owasp.esapi.ESAPI; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ ESAPI.class }) +public class ServerInfoSupplierTest { + @Rule + public TestName testName = new TestName(); + + private HttpServletRequest request; + + @Before + public void buildStaticMocks() { + request = mock(HttpServletRequest.class); + mockStatic(ESAPI.class); + } + + @Test + public void verifyFullOutput() throws Exception { + when(ESAPI.class, "currentRequest").thenReturn(request); + when(request.getLocalAddr()).thenReturn("LOCAL_ADDR"); + when(request.getLocalPort()).thenReturn(99999); + + ServerInfoSupplier sis = new ServerInfoSupplier(testName.getMethodName()); + sis.setLogApplicationName(true, testName.getMethodName() + "-APPLICATION"); + sis.setLogServerIp(true); + + String result = sis.get(); + assertEquals("LOCAL_ADDR:99999/" + testName.getMethodName() + "-APPLICATION/" + testName.getMethodName(), + result); + } + + @Test + public void verifyOutputNullRequest() throws Exception { + when(ESAPI.class, "currentRequest").thenReturn(null); + ServerInfoSupplier sis = new ServerInfoSupplier(testName.getMethodName()); + sis.setLogApplicationName(true, testName.getMethodName() + "-APPLICATION"); + sis.setLogServerIp(true); + + String result = sis.get(); + assertEquals("/" + testName.getMethodName() + "-APPLICATION/" + testName.getMethodName(), result); + } + + @Test + public void verifyOutputNoAppName() throws Exception { + when(ESAPI.class, "currentRequest").thenReturn(request); + when(request.getLocalAddr()).thenReturn("LOCAL_ADDR"); + when(request.getLocalPort()).thenReturn(99999); + + ServerInfoSupplier sis = new ServerInfoSupplier(testName.getMethodName()); + sis.setLogApplicationName(false, null); + sis.setLogServerIp(true); + + String result = sis.get(); + assertEquals("LOCAL_ADDR:99999/" + testName.getMethodName(), result); + } + + @Test + public void verifyOutputNullAppName() throws Exception { + when(ESAPI.class, "currentRequest").thenReturn(request); + when(request.getLocalAddr()).thenReturn("LOCAL_ADDR"); + when(request.getLocalPort()).thenReturn(99999); + + ServerInfoSupplier sis = new ServerInfoSupplier(testName.getMethodName()); + sis.setLogApplicationName(true, null); + sis.setLogServerIp(true); + + String result = sis.get(); + assertEquals("LOCAL_ADDR:99999/null/" + testName.getMethodName(), result); + } + + @Test + public void verifyOutputNoServerIp() { + ServerInfoSupplier sis = new ServerInfoSupplier(testName.getMethodName()); + sis.setLogApplicationName(true, testName.getMethodName() + "-APPLICATION"); + sis.setLogServerIp(false); + + String result = sis.get(); + assertEquals("/" + testName.getMethodName() + "-APPLICATION/" + testName.getMethodName(), result); + } + +} diff --git a/src/test/java/org/owasp/esapi/logging/appender/UserInfoSupplierTest.java b/src/test/java/org/owasp/esapi/logging/appender/UserInfoSupplierTest.java new file mode 100644 index 000000000..f873816f0 --- /dev/null +++ b/src/test/java/org/owasp/esapi/logging/appender/UserInfoSupplierTest.java @@ -0,0 +1,95 @@ +package org.owasp.esapi.logging.appender; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.when; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestName; +import org.junit.runner.RunWith; +import org.mockito.ArgumentMatchers; +import org.owasp.esapi.Authenticator; +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Randomizer; +import org.owasp.esapi.User; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ESAPI.class}) +@PowerMockIgnore("javax.security.*") //Required since User extends javax.security.Principal +public class UserInfoSupplierTest { + private static final String ESAPI_SESSION_ATTR = "ESAPI_SESSION"; + + @Rule + public TestName testName = new TestName(); + + private Authenticator mockAuth; + private User mockUser; + + @Before + public void before() throws Exception { + mockAuth =mock(Authenticator.class); + mockUser =mock(User.class); + + mockStatic(ESAPI.class); + when(ESAPI.class, "authenticator").thenReturn(mockAuth); + + when(mockUser.getAccountName()).thenReturn(testName.getMethodName() + "-USER"); + + + when(mockAuth.getCurrentUser()).thenReturn(mockUser); + } + + @Test + public void testHappyPath() throws Exception { + UserInfoSupplier uis = new UserInfoSupplier(); + uis.setLogUserInfo(true); + String result = uis.get(); + + assertEquals(testName.getMethodName() + "-USER", result); + + verify(mockAuth,times(1)).getCurrentUser(); + verify(mockUser,times(1)).getAccountName(); + + verifyNoMoreInteractions(mockAuth, mockUser); + } + + @Test + public void testLogUserOff() { + UserInfoSupplier uis = new UserInfoSupplier(); + uis.setLogUserInfo(false); + String result = uis.get(); + + assertTrue(result.isEmpty()); + verify(mockAuth,times(1)).getCurrentUser(); + + verifyNoMoreInteractions(mockAuth, mockUser); + } + + @Test + public void testLogUserNull() { + when(mockAuth.getCurrentUser()).thenReturn(null); + UserInfoSupplier uis = new UserInfoSupplier(); + uis.setLogUserInfo(true); + String result = uis.get(); + + assertEquals("#ANONYMOUS#", result); + + verify(mockAuth,times(1)).getCurrentUser(); + + verifyNoMoreInteractions(mockAuth, mockUser); + } + +} \ No newline at end of file diff --git a/src/test/java/org/owasp/esapi/logging/cleaning/CodecLogScrubberTest.java b/src/test/java/org/owasp/esapi/logging/cleaning/CodecLogScrubberTest.java new file mode 100644 index 000000000..8ca742673 --- /dev/null +++ b/src/test/java/org/owasp/esapi/logging/cleaning/CodecLogScrubberTest.java @@ -0,0 +1,73 @@ +/** + * 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. + * + * @created 2018 + */ +package org.owasp.esapi.logging.cleaning; + +import static org.junit.Assert.assertEquals; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.mockito.ArgumentCaptor; +import org.mockito.ArgumentMatchers; +import org.mockito.Mockito; +import org.owasp.esapi.codecs.Codec; + +public class CodecLogScrubberTest { + @Rule + public ExpectedException exEx = ExpectedException.none(); + + @Test + public void testNullCodecThrowsException() { + exEx.expect(IllegalArgumentException.class); + exEx.expectMessage("cannot be null"); + + new CodecLogScrubber(null, new char[0]); + } + + @Test + public void testNullImmuneIsEmpty() { + String message = "cleanThis"; + @SuppressWarnings("unchecked") + Codec mockCodec = Mockito.mock(Codec.class); + + CodecLogScrubber scrubber = new CodecLogScrubber(mockCodec, null); + + ArgumentCaptor immuneCapture = ArgumentCaptor.forClass(char[].class); + + scrubber.cleanMessage(message); + + Mockito.verify(mockCodec, Mockito.times(1)).encode(immuneCapture.capture(), ArgumentMatchers.matches(message)); + Mockito.verifyNoMoreInteractions(mockCodec); + + assertEquals(0, immuneCapture.getValue().length); + } + + @Test + public void testCleanMessage() { + char[] immune = new char[] { 'a', 'b', 'c' }; + String message = "cleanThis"; + @SuppressWarnings("unchecked") + Codec mockCodec = Mockito.mock(Codec.class); + + CodecLogScrubber scrubber = new CodecLogScrubber(mockCodec, immune); + + scrubber.cleanMessage(message); + + Mockito.verify(mockCodec, Mockito.times(1)).encode(ArgumentMatchers.same(immune), ArgumentMatchers.matches(message)); + Mockito.verifyNoMoreInteractions(mockCodec); + + } + +} diff --git a/src/test/java/org/owasp/esapi/logging/cleaning/CompositeLogScrubberTest.java b/src/test/java/org/owasp/esapi/logging/cleaning/CompositeLogScrubberTest.java new file mode 100644 index 000000000..fa11554b4 --- /dev/null +++ b/src/test/java/org/owasp/esapi/logging/cleaning/CompositeLogScrubberTest.java @@ -0,0 +1,68 @@ +/** + * 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. + * + * @created 2018 + */ +package org.owasp.esapi.logging.cleaning; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.Arrays; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.mockito.Mockito; + +public class CompositeLogScrubberTest { + + @Rule + public ExpectedException exEx = ExpectedException.none(); + + @Test + public void testNullListThrowsException() { + exEx.expect(IllegalArgumentException.class); + exEx.expectMessage("cannot be null"); + + new CompositeLogScrubber(null); + } + + @Test + public void testPassthroughOnEmpty() { + String str = "Testing Content"; + String cleaned = new CompositeLogScrubber(new ArrayList()).cleanMessage(str); + assertEquals(str, cleaned); + } + + @Test + public void testListIteration() { + LogScrubber scrub1 = Mockito.mock(LogScrubber.class); + LogScrubber scrub2 = Mockito.mock(LogScrubber.class); + CompositeLogScrubber scrubber = new CompositeLogScrubber(Arrays.asList(scrub1, scrub2)); + + String msg1 = "start"; + String msg2 = "scrub1 return"; + String msg3 = "scrub2 return"; + + Mockito.when(scrub1.cleanMessage(msg1)).thenReturn(msg2); + Mockito.when(scrub2.cleanMessage(msg2)).thenReturn(msg3); + + String cleaned = scrubber.cleanMessage(msg1); + + Mockito.verify(scrub1, Mockito.times(1)).cleanMessage(msg1); + Mockito.verify(scrub2, Mockito.times(1)).cleanMessage(msg2); + + assertEquals(msg3, cleaned); + } + +} diff --git a/src/test/java/org/owasp/esapi/logging/cleaning/NewlineLogScrubberTest.java b/src/test/java/org/owasp/esapi/logging/cleaning/NewlineLogScrubberTest.java new file mode 100644 index 000000000..810f3f210 --- /dev/null +++ b/src/test/java/org/owasp/esapi/logging/cleaning/NewlineLogScrubberTest.java @@ -0,0 +1,42 @@ +/** + * 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. + * + * @created 2018 + */ +package org.owasp.esapi.logging.cleaning; + +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +public class NewlineLogScrubberTest { + + private NewlineLogScrubber scrubber = new NewlineLogScrubber(); + + @Test + public void testReplaceR() { + String cleanedr = scrubber.cleanMessage("\r"); + assertEquals("_", cleanedr); + } + + @Test + public void testReplaceN() { + String cleanedc = scrubber.cleanMessage("\n"); + assertEquals("_", cleanedc); + } + + @Test + public void testNoReplacement() { + String cleanedc = scrubber.cleanMessage("This content should remain unchanged"); + assertEquals("This content should remain unchanged", cleanedc); + } + +} diff --git a/src/test/java/org/owasp/esapi/logging/java/JavaLogBridgeImplTest.java b/src/test/java/org/owasp/esapi/logging/java/JavaLogBridgeImplTest.java new file mode 100644 index 000000000..b2928f4bf --- /dev/null +++ b/src/test/java/org/owasp/esapi/logging/java/JavaLogBridgeImplTest.java @@ -0,0 +1,162 @@ +/** + * 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. + * + * @created 2019 + */ +package org.owasp.esapi.logging.java; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.TestName; +import org.mockito.ArgumentMatchers; +import org.mockito.Mockito; +import org.owasp.esapi.Logger; +import org.owasp.esapi.Logger.EventType; +import org.owasp.esapi.logging.appender.LogAppender; +import org.owasp.esapi.logging.cleaning.LogScrubber; + +public class JavaLogBridgeImplTest { + + @Rule + public TestName testName = new TestName(); + @Rule + public ExpectedException exEx = ExpectedException.none(); + + private LogScrubber mockScrubber = Mockito.mock(LogScrubber.class); + private LogAppender mockAppender = Mockito.mock(LogAppender.class); + private JavaLogLevelHandler mockHandler = Mockito.mock(JavaLogLevelHandler.class); + private java.util.logging.Logger javaLogSpy; + private Throwable testEx = new Throwable(testName.getMethodName()); + private JavaLogBridge bridge; + + @Before + public void setup() { + Map levelLookup = new HashMap<>(); + levelLookup.put(Logger.ALL, mockHandler); + + java.util.logging.Logger wrappedLogger = java.util.logging.Logger.getLogger(testName.getMethodName()); + javaLogSpy = Mockito.spy(wrappedLogger); + bridge = new JavaLogBridgeImpl(mockAppender, mockScrubber, levelLookup); + } + + @Test + public void testLogMessageWithUnmappedEsapiLevelThrowsException() { + exEx.expect(IllegalArgumentException.class); + exEx.expectMessage("Unable to lookup Java level mapping"); + Map emptyMap = Collections.emptyMap(); + new JavaLogBridgeImpl(mockAppender, mockScrubber, emptyMap).log(javaLogSpy, 0, Logger.EVENT_UNSPECIFIED, "This Should fail"); + } + + @Test + public void testLogMessageAndExceptionWithUnmappedEsapiLevelThrowsException() { + exEx.expect(IllegalArgumentException.class); + exEx.expectMessage("Unable to lookup Java level mapping"); + Map emptyMap = Collections.emptyMap(); + new JavaLogBridgeImpl(mockAppender, mockScrubber, emptyMap).log(javaLogSpy, 0, Logger.EVENT_UNSPECIFIED, "This Should fail", testEx); + } + + @Test + public void testLogMessage() { + EventType eventType = Logger.EVENT_UNSPECIFIED; + String loggerName = testName.getMethodName() + "-LOGGER"; + String orignMsg = testName.getMethodName(); + String appendMsg = "[APPEND] " + orignMsg; + String cleanMsg = appendMsg + " [CLEANED]"; + + //Setup for Appender + Mockito.when(javaLogSpy.getName()).thenReturn(loggerName); + Mockito.when(mockAppender.appendTo(loggerName, eventType, orignMsg)).thenReturn(appendMsg); + //Setup for Scrubber + Mockito.when(mockScrubber.cleanMessage(appendMsg)).thenReturn(cleanMsg); + //Setup for Delegate Handler + Mockito.when(mockHandler.isEnabled(javaLogSpy)).thenReturn(true); + + bridge.log(javaLogSpy, Logger.ALL, eventType, testName.getMethodName()); + + Mockito.verify(javaLogSpy, Mockito.atLeastOnce()).getName(); + Mockito.verify(mockAppender, Mockito.times(1)).appendTo(loggerName, eventType, testName.getMethodName()); + Mockito.verify(mockScrubber, Mockito.times(1)).cleanMessage(appendMsg); + Mockito.verify(mockHandler, Mockito.times(1)).isEnabled(javaLogSpy); + Mockito.verify(mockHandler, Mockito.times(0)).log(ArgumentMatchers.any(java.util.logging.Logger.class), ArgumentMatchers.any(String.class), ArgumentMatchers.any(Throwable.class)); + Mockito.verify(mockHandler, Mockito.times(1)).log(ArgumentMatchers.same(javaLogSpy), ArgumentMatchers.eq(cleanMsg)); + + Mockito.verifyNoMoreInteractions(javaLogSpy, mockAppender, mockScrubber,mockHandler); + } + + @Test + public void testLogErrorMessageWithException() { + EventType eventType = Logger.EVENT_UNSPECIFIED; + String loggerName = testName.getMethodName() + "-LOGGER"; + String orignMsg = testName.getMethodName(); + String appendMsg = "[APPEND] " + orignMsg; + String cleanMsg = appendMsg + " [CLEANED]"; + + //Setup for Appender + Mockito.when(javaLogSpy.getName()).thenReturn(loggerName); + Mockito.when(mockAppender.appendTo(loggerName, eventType, orignMsg)).thenReturn(appendMsg); + //Setup for Scrubber + Mockito.when(mockScrubber.cleanMessage(appendMsg)).thenReturn(cleanMsg); + //Setup for Delegate Handler + Mockito.when(mockHandler.isEnabled(javaLogSpy)).thenReturn(true); + + bridge.log(javaLogSpy, Logger.ALL, eventType, testName.getMethodName(), testEx); + + Mockito.verify(javaLogSpy, Mockito.atLeastOnce()).getName(); + Mockito.verify(mockAppender, Mockito.times(1)).appendTo(loggerName, eventType, testName.getMethodName()); + Mockito.verify(mockScrubber, Mockito.times(1)).cleanMessage(appendMsg); + Mockito.verify(mockHandler, Mockito.times(1)).isEnabled(javaLogSpy); + Mockito.verify(mockHandler, Mockito.times(0)).log(ArgumentMatchers.any(java.util.logging.Logger.class), ArgumentMatchers.any(String.class)); + + Mockito.verify(mockHandler, Mockito.times(1)).log(ArgumentMatchers.same(javaLogSpy), ArgumentMatchers.eq(cleanMsg), ArgumentMatchers.same(testEx)); + + Mockito.verifyNoMoreInteractions(javaLogSpy, mockAppender, mockScrubber,mockHandler); + } + + + @Test + public void testDisabledLogMessage() { + Mockito.when(mockHandler.isEnabled(javaLogSpy)).thenReturn(false); + + bridge.log(javaLogSpy, Logger.ALL, Logger.EVENT_UNSPECIFIED, testName.getMethodName()); + + Mockito.verify(mockHandler, Mockito.times(1)).isEnabled(javaLogSpy); + Mockito.verify(mockScrubber, Mockito.times(0)).cleanMessage(ArgumentMatchers.anyString()); + Mockito.verify(mockHandler, Mockito.times(0)).log(ArgumentMatchers.any(java.util.logging.Logger.class), ArgumentMatchers.any(String.class)); + Mockito.verify(mockHandler, Mockito.times(0)).log(ArgumentMatchers.any(java.util.logging.Logger.class), ArgumentMatchers.any(String.class), ArgumentMatchers.any(Throwable.class)); + } + + @Test + public void testDisabledErrorLogWithException() { + Mockito.when(mockHandler.isEnabled(javaLogSpy)).thenReturn(false); + + bridge.log(javaLogSpy, Logger.ALL, Logger.EVENT_UNSPECIFIED, testName.getMethodName(), testEx); + + Mockito.verify(mockHandler, Mockito.times(1)).isEnabled(javaLogSpy); + Mockito.verify(mockScrubber, Mockito.times(0)).cleanMessage(ArgumentMatchers.anyString()); + Mockito.verify(mockHandler, Mockito.times(0)).log(ArgumentMatchers.any(java.util.logging.Logger.class), ArgumentMatchers.any(String.class)); + Mockito.verify(mockHandler, Mockito.times(0)).log(ArgumentMatchers.any(java.util.logging.Logger.class), ArgumentMatchers.any(String.class), ArgumentMatchers.any(Throwable.class)); + + } + + @Test + public void testNullEventTypeWorks() + { + // would throw an exception if the null wasn't handled properly + bridge.log(javaLogSpy, Logger.ALL, null, testName.getMethodName()); + } +} diff --git a/src/test/java/org/owasp/esapi/logging/java/JavaLogFactoryTest.java b/src/test/java/org/owasp/esapi/logging/java/JavaLogFactoryTest.java new file mode 100644 index 000000000..201a3c42a --- /dev/null +++ b/src/test/java/org/owasp/esapi/logging/java/JavaLogFactoryTest.java @@ -0,0 +1,112 @@ +/** + * 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. + * + * @created 2019 + */ +package org.owasp.esapi.logging.java; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.TestName; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.owasp.esapi.Logger; +import org.owasp.esapi.logging.appender.LogAppender; +import org.owasp.esapi.logging.appender.LogPrefixAppender; +import org.owasp.esapi.logging.cleaning.CodecLogScrubber; +import org.owasp.esapi.logging.cleaning.CompositeLogScrubber; +import org.owasp.esapi.logging.cleaning.LogScrubber; +import org.owasp.esapi.logging.cleaning.NewlineLogScrubber; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +@RunWith(PowerMockRunner.class) +@PrepareForTest (JavaLogFactory.class) +public class JavaLogFactoryTest { + @Rule + public TestName testName = new TestName(); + + @Rule + public ExpectedException exEx = ExpectedException.none(); + + @Test + public void testCreateLoggerByString() { + Logger logger = new JavaLogFactory().getLogger("test"); + Assert.assertTrue(logger instanceof JavaLogger); + } + + @Test public void testCreateLoggerByClass() { + Logger logger = new JavaLogFactory().getLogger(JavaLogBridgeImplTest.class); + Assert.assertTrue(logger instanceof JavaLogger); + } + + @Test + public void checkScrubberWithEncoding() throws Exception { + ArgumentCaptor delegates = ArgumentCaptor.forClass(List.class); + PowerMockito.whenNew(CompositeLogScrubber.class).withArguments(delegates.capture()).thenReturn(null); + + //Call to invoke the constructor capture + JavaLogFactory.createLogScrubber(true); + + List scrubbers = delegates.getValue(); + Assert.assertEquals(2, scrubbers.size()); + Assert.assertTrue(scrubbers.get(0) instanceof NewlineLogScrubber); + Assert.assertTrue(scrubbers.get(1) instanceof CodecLogScrubber); + } + + @Test + public void checkScrubberWithoutEncoding() throws Exception { + ArgumentCaptor delegates = ArgumentCaptor.forClass(List.class); + PowerMockito.whenNew(CompositeLogScrubber.class).withArguments(delegates.capture()).thenReturn(null); + + //Call to invoke the constructor capture + JavaLogFactory.createLogScrubber(false); + + List scrubbers = delegates.getValue(); + Assert.assertEquals(1, scrubbers.size()); + Assert.assertTrue(scrubbers.get(0) instanceof NewlineLogScrubber); + } + + /** + * At this time there are no special considerations or handling for the appender + * creation in this scope. It is expected that the arguments to the internal + * creation method are passed directly to the constructor of the + * LogPrefixAppender with no mutation or additional validation. + */ + @Test + public void checkPassthroughAppenderConstruct() throws Exception { + LogPrefixAppender stubAppender = new LogPrefixAppender(true, true, true, true, ""); + ArgumentCaptor userInfoCapture = ArgumentCaptor.forClass(Boolean.class); + ArgumentCaptor clientInfoCapture = ArgumentCaptor.forClass(Boolean.class); + ArgumentCaptor serverInfoCapture = ArgumentCaptor.forClass(Boolean.class); + ArgumentCaptor logAppNameCapture = ArgumentCaptor.forClass(Boolean.class); + ArgumentCaptor appNameCapture = ArgumentCaptor.forClass(String.class); + + PowerMockito.whenNew(LogPrefixAppender.class).withArguments(userInfoCapture.capture(), clientInfoCapture.capture(), serverInfoCapture.capture(), logAppNameCapture.capture(), appNameCapture.capture()).thenReturn(stubAppender); + + LogAppender appender = JavaLogFactory.createLogAppender(true, true, false, true, testName.getMethodName()); + + Assert.assertEquals(stubAppender, appender); + Assert.assertTrue(userInfoCapture.getValue()); + Assert.assertTrue(clientInfoCapture.getValue()); + Assert.assertFalse(serverInfoCapture.getValue()); + Assert.assertTrue(logAppNameCapture.getValue()); + Assert.assertEquals(testName.getMethodName(), appNameCapture.getValue()); + } + + +} diff --git a/src/test/java/org/owasp/esapi/logging/java/JavaLogLevelHandlersTest.java b/src/test/java/org/owasp/esapi/logging/java/JavaLogLevelHandlersTest.java new file mode 100644 index 000000000..62c5a1d9a --- /dev/null +++ b/src/test/java/org/owasp/esapi/logging/java/JavaLogLevelHandlersTest.java @@ -0,0 +1,116 @@ +/** + * 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. + * + * @created 2019 + */ +package org.owasp.esapi.logging.java; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestName; +import org.mockito.Mockito; + +public class JavaLogLevelHandlersTest { + + private Logger mockLogger = Mockito.mock(Logger.class); + @Rule + public TestName testName = new TestName(); + + private Throwable testException = new Throwable("Expected for testing"); + + @Test + public void testErrorDelegation() { + JavaLogLevelHandlers.ERROR.isEnabled(mockLogger); + JavaLogLevelHandlers.ERROR.log(mockLogger, testName.getMethodName()); + JavaLogLevelHandlers.ERROR.log(mockLogger, testName.getMethodName(), testException); + + Level expectedJavaLevel = ESAPICustomJavaLevel.ERROR_LEVEL; + + Mockito.verify(mockLogger, Mockito.times(1)).isLoggable(expectedJavaLevel); + Mockito.verify(mockLogger, Mockito.times(1)).log(expectedJavaLevel, testName.getMethodName()); + Mockito.verify(mockLogger, Mockito.times(1)).log(expectedJavaLevel, testName.getMethodName(), testException); + Mockito.verifyNoMoreInteractions(mockLogger); + } + + @Test + public void testAlwaysDelegation() { + JavaLogLevelHandlers.ALWAYS.isEnabled(mockLogger); + JavaLogLevelHandlers.ALWAYS.log(mockLogger, testName.getMethodName()); + JavaLogLevelHandlers.ALWAYS.log(mockLogger, testName.getMethodName(), testException); + + Level expectedJavaLevel = ESAPICustomJavaLevel.ALWAYS_LEVEL; + + Mockito.verify(mockLogger, Mockito.times(1)).isLoggable(expectedJavaLevel); + Mockito.verify(mockLogger, Mockito.times(1)).log(expectedJavaLevel, testName.getMethodName()); + Mockito.verify(mockLogger, Mockito.times(1)).log(expectedJavaLevel, testName.getMethodName(), testException); + Mockito.verifyNoMoreInteractions(mockLogger); + } + + @Test + public void testWarnDelegation() { + JavaLogLevelHandlers.WARNING.isEnabled(mockLogger); + JavaLogLevelHandlers.WARNING.log(mockLogger, testName.getMethodName()); + JavaLogLevelHandlers.WARNING.log(mockLogger, testName.getMethodName(), testException); + + Level expectedJavaLevel = Level.WARNING; + + Mockito.verify(mockLogger, Mockito.times(1)).isLoggable(expectedJavaLevel); + Mockito.verify(mockLogger, Mockito.times(1)).log(expectedJavaLevel, testName.getMethodName()); + Mockito.verify(mockLogger, Mockito.times(1)).log(expectedJavaLevel, testName.getMethodName(), testException); + Mockito.verifyNoMoreInteractions(mockLogger); + } + @Test + public void testInfoDelegation() { + JavaLogLevelHandlers.INFO.isEnabled(mockLogger); + JavaLogLevelHandlers.INFO.log(mockLogger, testName.getMethodName()); + JavaLogLevelHandlers.INFO.log(mockLogger, testName.getMethodName(), testException); + + Level expectedJavaLevel = Level.INFO; + + Mockito.verify(mockLogger, Mockito.times(1)).isLoggable(expectedJavaLevel); + Mockito.verify(mockLogger, Mockito.times(1)).log(expectedJavaLevel, testName.getMethodName()); + Mockito.verify(mockLogger, Mockito.times(1)).log(expectedJavaLevel, testName.getMethodName(), testException); + + Mockito.verifyNoMoreInteractions(mockLogger); + } + @Test + public void testDebugDelegation() { + JavaLogLevelHandlers.FINE.isEnabled(mockLogger); + JavaLogLevelHandlers.FINE.log(mockLogger, testName.getMethodName()); + JavaLogLevelHandlers.FINE.log(mockLogger, testName.getMethodName(), testException); + + Level expectedJavaLevel = Level.FINE; + + Mockito.verify(mockLogger, Mockito.times(1)).isLoggable(expectedJavaLevel); + Mockito.verify(mockLogger, Mockito.times(1)).log(expectedJavaLevel, testName.getMethodName()); + Mockito.verify(mockLogger, Mockito.times(1)).log(expectedJavaLevel, testName.getMethodName(), testException); + + Mockito.verifyNoMoreInteractions(mockLogger); + } + @Test + public void testTraceDelegation() { + JavaLogLevelHandlers.FINEST.isEnabled(mockLogger); + JavaLogLevelHandlers.FINEST.log(mockLogger, testName.getMethodName()); + JavaLogLevelHandlers.FINEST.log(mockLogger, testName.getMethodName(), testException); + + Level expectedJavaLevel = Level.FINEST; + + Mockito.verify(mockLogger, Mockito.times(1)).isLoggable(expectedJavaLevel); + Mockito.verify(mockLogger, Mockito.times(1)).log(expectedJavaLevel, testName.getMethodName()); + Mockito.verify(mockLogger, Mockito.times(1)).log(expectedJavaLevel, testName.getMethodName(), testException); + + Mockito.verifyNoMoreInteractions(mockLogger); + } +} diff --git a/src/test/java/org/owasp/esapi/logging/java/JavaLoggerTest.java b/src/test/java/org/owasp/esapi/logging/java/JavaLoggerTest.java new file mode 100644 index 000000000..906bb6434 --- /dev/null +++ b/src/test/java/org/owasp/esapi/logging/java/JavaLoggerTest.java @@ -0,0 +1,297 @@ +/** + * 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. + * + * @created 2019 + */ + +package org.owasp.esapi.logging.java; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestName; +import org.mockito.Mockito; +import org.owasp.esapi.Logger; + +public class JavaLoggerTest { + @Rule + public TestName testName = new TestName(); + + private static final String MSG = JavaLoggerTest.class.getSimpleName(); + + private JavaLogBridge mockBridge = Mockito.mock(JavaLogBridge.class); + private java.util.logging.Logger javaLogSpy; + + private Throwable testEx = new Throwable(MSG + "_Exception"); + private Logger testLogger; + + @Before + public void setup() { + java.util.logging.Logger wrappedLogger = java.util.logging.Logger.getLogger(testName.getMethodName()); + javaLogSpy = Mockito.spy(wrappedLogger); + testLogger = new JavaLogger(javaLogSpy, mockBridge, Logger.ALL); + } + + @Test + public void testLevelEnablement() { + testLogger.setLevel(Logger.INFO); + + Assert.assertTrue(testLogger.isFatalEnabled()); + Assert.assertTrue(testLogger.isErrorEnabled()); + Assert.assertTrue(testLogger.isWarningEnabled()); + Assert.assertTrue(testLogger.isInfoEnabled()); + Assert.assertFalse(testLogger.isDebugEnabled()); + Assert.assertFalse(testLogger.isTraceEnabled()); + + Assert.assertEquals(Logger.INFO, testLogger.getESAPILevel()); + } + + @Test + public void testAllLevelEnablement() { + testLogger.setLevel(Logger.ALL); + + Assert.assertTrue(testLogger.isFatalEnabled()); + Assert.assertTrue(testLogger.isErrorEnabled()); + Assert.assertTrue(testLogger.isWarningEnabled()); + Assert.assertTrue(testLogger.isInfoEnabled()); + Assert.assertTrue(testLogger.isDebugEnabled()); + Assert.assertTrue(testLogger.isTraceEnabled()); + } + + @Test + public void testOffLevelEnablement() { + testLogger.setLevel(Logger.OFF); + + Assert.assertFalse(testLogger.isFatalEnabled()); + Assert.assertFalse(testLogger.isErrorEnabled()); + Assert.assertFalse(testLogger.isWarningEnabled()); + Assert.assertFalse(testLogger.isInfoEnabled()); + Assert.assertFalse(testLogger.isDebugEnabled()); + Assert.assertFalse(testLogger.isTraceEnabled()); + } + @Test + public void testFatalWithMessage() { + testLogger.fatal(Logger.EVENT_UNSPECIFIED, MSG); + + Mockito.verify(mockBridge, Mockito.times(1)).log(javaLogSpy, Logger.FATAL, Logger.EVENT_UNSPECIFIED, MSG); + Mockito.verifyNoMoreInteractions(mockBridge, javaLogSpy); + } + @Test + public void testFatalWithMessageAndThrowable() { + testLogger.fatal(Logger.EVENT_UNSPECIFIED, MSG, testEx); + + Mockito.verify(mockBridge, Mockito.times(1)).log(javaLogSpy, Logger.FATAL, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, javaLogSpy); + } + + @Test + public void testFatalWithMessageDisabled() { + testLogger.setLevel(Logger.OFF); + testLogger.fatal(Logger.EVENT_UNSPECIFIED, MSG); + + Mockito.verify(mockBridge, Mockito.times(0)).log(javaLogSpy, Logger.FATAL, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, javaLogSpy); + } + @Test + public void testFatalWithMessageAndThrowableDisabled() { + testLogger.setLevel(Logger.OFF); + testLogger.fatal(Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verify(mockBridge, Mockito.times(0)).log(javaLogSpy, Logger.FATAL, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, javaLogSpy); + } + + @Test + public void testErrorWithMessage() { + testLogger.error(Logger.EVENT_UNSPECIFIED, MSG); + + Mockito.verify(mockBridge, Mockito.times(1)).log(javaLogSpy, Logger.ERROR, Logger.EVENT_UNSPECIFIED, MSG); + Mockito.verifyNoMoreInteractions(mockBridge, javaLogSpy); + } + @Test + public void testErrorWithMessageAndThrowable() { + testLogger.error(Logger.EVENT_UNSPECIFIED, MSG, testEx); + + Mockito.verify(mockBridge, Mockito.times(1)).log(javaLogSpy, Logger.ERROR, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, javaLogSpy); + } + + @Test + public void testErrorWithMessageDisabled() { + testLogger.setLevel(Logger.OFF); + testLogger.error(Logger.EVENT_UNSPECIFIED, MSG); + + Mockito.verify(mockBridge, Mockito.times(0)).log(javaLogSpy, Logger.ERROR, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, javaLogSpy); + } + @Test + public void testErrorWithMessageAndThrowableDisabled() { + testLogger.setLevel(Logger.OFF); + testLogger.error(Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verify(mockBridge, Mockito.times(0)).log(javaLogSpy, Logger.ERROR, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, javaLogSpy); + } + + @Test + public void testWarnWithMessage() { + testLogger.warning(Logger.EVENT_UNSPECIFIED, MSG); + + Mockito.verify(mockBridge, Mockito.times(1)).log(javaLogSpy, Logger.WARNING, Logger.EVENT_UNSPECIFIED, MSG); + Mockito.verifyNoMoreInteractions(mockBridge, javaLogSpy); + } + @Test + public void testWarnWithMessageAndThrowable() { + testLogger.warning(Logger.EVENT_UNSPECIFIED, MSG, testEx); + + Mockito.verify(mockBridge, Mockito.times(1)).log(javaLogSpy, Logger.WARNING, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, javaLogSpy); + } + + @Test + public void testWarnWithMessageDisabled() { + testLogger.setLevel(Logger.OFF); + testLogger.warning(Logger.EVENT_UNSPECIFIED, MSG); + + Mockito.verify(mockBridge, Mockito.times(0)).log(javaLogSpy, Logger.WARNING, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, javaLogSpy); + } + @Test + public void testWarnWithMessageAndThrowableDisabled() { + testLogger.setLevel(Logger.OFF); + testLogger.warning(Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verify(mockBridge, Mockito.times(0)).log(javaLogSpy, Logger.WARNING, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, javaLogSpy); + } + + @Test + public void testInfoWithMessage() { + testLogger.info(Logger.EVENT_UNSPECIFIED, MSG); + + Mockito.verify(mockBridge, Mockito.times(1)).log(javaLogSpy, Logger.INFO, Logger.EVENT_UNSPECIFIED, MSG); + Mockito.verifyNoMoreInteractions(mockBridge, javaLogSpy); + } + @Test + public void testInfoWithMessageAndThrowable() { + testLogger.info(Logger.EVENT_UNSPECIFIED, MSG, testEx); + + Mockito.verify(mockBridge, Mockito.times(1)).log(javaLogSpy, Logger.INFO, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, javaLogSpy); + } + + @Test + public void testInfoWithMessageDisabled() { + testLogger.setLevel(Logger.OFF); + testLogger.info(Logger.EVENT_UNSPECIFIED, MSG); + + Mockito.verify(mockBridge, Mockito.times(0)).log(javaLogSpy, Logger.INFO, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, javaLogSpy); + } + @Test + public void testInfoWithMessageAndThrowableDisabled() { + testLogger.setLevel(Logger.OFF); + testLogger.info(Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verify(mockBridge, Mockito.times(0)).log(javaLogSpy, Logger.INFO, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, javaLogSpy); + } + @Test + public void testDebugWithMessage() { + testLogger.debug(Logger.EVENT_UNSPECIFIED, MSG); + + Mockito.verify(mockBridge, Mockito.times(1)).log(javaLogSpy, Logger.DEBUG, Logger.EVENT_UNSPECIFIED, MSG); + Mockito.verifyNoMoreInteractions(mockBridge, javaLogSpy); + } + @Test + public void testDebugWithMessageAndThrowable() { + testLogger.debug(Logger.EVENT_UNSPECIFIED, MSG, testEx); + + Mockito.verify(mockBridge, Mockito.times(1)).log(javaLogSpy, Logger.DEBUG, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, javaLogSpy); + } + + @Test + public void testDebugWithMessageDisabled() { + testLogger.setLevel(Logger.OFF); + testLogger.debug(Logger.EVENT_UNSPECIFIED, MSG); + + Mockito.verify(mockBridge, Mockito.times(0)).log(javaLogSpy, Logger.DEBUG, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, javaLogSpy); + } + @Test + public void testDebugWithMessageAndThrowableDisabled() { + testLogger.setLevel(Logger.OFF); + testLogger.debug(Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verify(mockBridge, Mockito.times(0)).log(javaLogSpy, Logger.DEBUG, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, javaLogSpy); + } + + @Test + public void testTraceWithMessage() { + testLogger.trace(Logger.EVENT_UNSPECIFIED, MSG); + + Mockito.verify(mockBridge, Mockito.times(1)).log(javaLogSpy, Logger.TRACE, Logger.EVENT_UNSPECIFIED, MSG); + Mockito.verifyNoMoreInteractions(mockBridge, javaLogSpy); + } + @Test + public void testTraceWithMessageAndThrowable() { + testLogger.trace(Logger.EVENT_UNSPECIFIED, MSG, testEx); + + Mockito.verify(mockBridge, Mockito.times(1)).log(javaLogSpy, Logger.TRACE, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, javaLogSpy); + } + + @Test + public void testTraceWithMessageDisabled() { + testLogger.setLevel(Logger.OFF); + testLogger.trace(Logger.EVENT_UNSPECIFIED, MSG); + + Mockito.verify(mockBridge, Mockito.times(0)).log(javaLogSpy, Logger.TRACE, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, javaLogSpy); + } + @Test + public void testTraceWithMessageAndThrowableDisabled() { + testLogger.setLevel(Logger.OFF); + testLogger.trace(Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verify(mockBridge, Mockito.times(0)).log(javaLogSpy, Logger.TRACE, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, javaLogSpy); + } + + @Test + public void testAlwaysWithMessage() { + testLogger.always(Logger.EVENT_UNSPECIFIED, MSG); + + Mockito.verify(mockBridge, Mockito.times(1)).log(javaLogSpy, Logger.ALL, Logger.EVENT_UNSPECIFIED, MSG); + Mockito.verifyNoMoreInteractions(mockBridge, javaLogSpy); + } + @Test + public void testAlwaysWithMessageAndThrowable() { + testLogger.always(Logger.EVENT_UNSPECIFIED, MSG, testEx); + + Mockito.verify(mockBridge, Mockito.times(1)).log(javaLogSpy, Logger.ALL, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, javaLogSpy); + } + + @Test + public void testAlwaysWithMessageDisabled() { + testLogger.setLevel(Logger.OFF); + testLogger.always(Logger.EVENT_UNSPECIFIED, MSG); + + Mockito.verify(mockBridge, Mockito.times(0)).log(javaLogSpy, Logger.ALL, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, javaLogSpy); + } + @Test + public void testAlwaysWithMessageAndThrowableDisabled() { + testLogger.setLevel(Logger.OFF); + testLogger.always(Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verify(mockBridge, Mockito.times(0)).log(javaLogSpy, Logger.ALL, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, javaLogSpy); + } +} diff --git a/src/test/java/org/owasp/esapi/logging/slf4j/Slf4JLogBridgeImplTest.java b/src/test/java/org/owasp/esapi/logging/slf4j/Slf4JLogBridgeImplTest.java new file mode 100644 index 000000000..97398d9da --- /dev/null +++ b/src/test/java/org/owasp/esapi/logging/slf4j/Slf4JLogBridgeImplTest.java @@ -0,0 +1,179 @@ +/** + * 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. + * + * @created 2018 + */ +package org.owasp.esapi.logging.slf4j; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.TestName; +import org.mockito.ArgumentCaptor; +import org.mockito.ArgumentMatchers; +import org.mockito.Mockito; +import org.owasp.esapi.Logger; +import org.owasp.esapi.Logger.EventType; +import org.owasp.esapi.logging.appender.LogAppender; +import org.owasp.esapi.logging.cleaning.LogScrubber; +import org.slf4j.Marker; + +public class Slf4JLogBridgeImplTest { + + @Rule + public TestName testName = new TestName(); + @Rule + public ExpectedException exEx = ExpectedException.none(); + + private LogScrubber mockScrubber = Mockito.mock(LogScrubber.class); + private LogAppender mockAppender = Mockito.mock(LogAppender.class); + private Slf4JLogLevelHandler mockHandler = Mockito.mock(Slf4JLogLevelHandler.class); + private org.slf4j.Logger mockSlf4JLogger = Mockito.mock(org.slf4j.Logger.class); + private Throwable testEx = new Throwable(testName.getMethodName()); + private Slf4JLogBridge bridge; + + @Before + public void setup() { + Map levelLookup = new HashMap<>(); + levelLookup.put(Logger.ALL, mockHandler); + levelLookup.put(Logger.ERROR, mockHandler); + + bridge = new Slf4JLogBridgeImpl(mockAppender, mockScrubber, levelLookup); + } + + @Test + public void testLogMessageWithUnmappedEsapiLevelThrowsException() { + exEx.expect(IllegalArgumentException.class); + exEx.expectMessage("Unable to lookup SLF4J level mapping"); + Map emptyMap = Collections.emptyMap(); + new Slf4JLogBridgeImpl(mockAppender, mockScrubber, emptyMap).log(mockSlf4JLogger, 0, Logger.EVENT_UNSPECIFIED, "This Should fail"); + } + + @Test + public void testLogMessageAndExceptionWithUnmappedEsapiLevelThrowsException() { + exEx.expect(IllegalArgumentException.class); + exEx.expectMessage("Unable to lookup SLF4J level mapping"); + Map emptyMap = Collections.emptyMap(); + new Slf4JLogBridgeImpl(mockAppender, mockScrubber, emptyMap).log(mockSlf4JLogger, 0, Logger.EVENT_UNSPECIFIED, "This Should fail", testEx); + } + + @Test + public void testLogMessage() { + EventType eventType = Logger.EVENT_UNSPECIFIED; + String loggerName = testName.getMethodName() + "-LOGGER"; + String orignMsg = testName.getMethodName(); + String appendMsg = "[APPEND] " + orignMsg; + String cleanMsg = appendMsg + " [CLEANED]"; + + //Setup for Appender + Mockito.when(mockSlf4JLogger.getName()).thenReturn(loggerName); + Mockito.when(mockAppender.appendTo(loggerName, eventType, orignMsg)).thenReturn(appendMsg); + //Setup for Scrubber + Mockito.when(mockScrubber.cleanMessage(appendMsg)).thenReturn(cleanMsg); + //Setup for Delegate Handler + ArgumentCaptor markerCapture = ArgumentCaptor.forClass(Marker.class); + Mockito.when(mockHandler.isEnabled(mockSlf4JLogger)).thenReturn(true); + + bridge.log(mockSlf4JLogger, Logger.ALL, eventType, testName.getMethodName()); + + Mockito.verify(mockSlf4JLogger, Mockito.atLeastOnce()).getName(); + Mockito.verify(mockAppender, Mockito.times(1)).appendTo(loggerName, eventType, testName.getMethodName()); + Mockito.verify(mockScrubber, Mockito.times(1)).cleanMessage(appendMsg); + Mockito.verify(mockHandler, Mockito.times(1)).isEnabled(mockSlf4JLogger); + Mockito.verify(mockHandler, Mockito.times(0)).log(ArgumentMatchers.any(org.slf4j.Logger.class), ArgumentMatchers.any(Marker.class), ArgumentMatchers.any(String.class), ArgumentMatchers.any(Throwable.class)); + Mockito.verify(mockHandler, Mockito.times(1)).log(ArgumentMatchers.same(mockSlf4JLogger), markerCapture.capture(), ArgumentMatchers.eq(cleanMsg)); + + Assert.assertEquals(Logger.EVENT_UNSPECIFIED.toString(), markerCapture.getValue().getName()); + Mockito.verifyNoMoreInteractions(mockSlf4JLogger, mockAppender, mockScrubber,mockHandler); + } + + @Test + public void testLogErrorMessageWithException() { + EventType eventType = Logger.EVENT_UNSPECIFIED; + String loggerName = testName.getMethodName() + "-LOGGER"; + String orignMsg = testName.getMethodName(); + String appendMsg = "[APPEND] " + orignMsg; + String cleanMsg = appendMsg + " [CLEANED]"; + + //Setup for Appender + Mockito.when(mockSlf4JLogger.getName()).thenReturn(loggerName); + Mockito.when(mockAppender.appendTo(loggerName, eventType, orignMsg)).thenReturn(appendMsg); + //Setup for Scrubber + Mockito.when(mockScrubber.cleanMessage(appendMsg)).thenReturn(cleanMsg); + //Setup for Delegate Handler + ArgumentCaptor markerCapture = ArgumentCaptor.forClass(Marker.class); + Mockito.when(mockHandler.isEnabled(mockSlf4JLogger)).thenReturn(true); + + bridge.log(mockSlf4JLogger, Logger.ALL, eventType, testName.getMethodName(), testEx); + + Mockito.verify(mockSlf4JLogger, Mockito.atLeastOnce()).getName(); + Mockito.verify(mockAppender, Mockito.times(1)).appendTo(loggerName, eventType, testName.getMethodName()); + Mockito.verify(mockScrubber, Mockito.times(1)).cleanMessage(appendMsg); + Mockito.verify(mockHandler, Mockito.times(1)).isEnabled(mockSlf4JLogger); + Mockito.verify(mockHandler, Mockito.times(0)).log(ArgumentMatchers.any(org.slf4j.Logger.class), ArgumentMatchers.any(Marker.class), ArgumentMatchers.any(String.class)); + + Mockito.verify(mockHandler, Mockito.times(1)).log(ArgumentMatchers.same(mockSlf4JLogger), markerCapture.capture(), ArgumentMatchers.eq(cleanMsg), ArgumentMatchers.same(testEx)); + + Assert.assertEquals(Logger.EVENT_UNSPECIFIED.toString(), markerCapture.getValue().getName()); + Mockito.verifyNoMoreInteractions(mockSlf4JLogger, mockAppender, mockScrubber,mockHandler); + } + + + @Test + public void testDisabledLogMessage() { + Mockito.when(mockHandler.isEnabled(mockSlf4JLogger)).thenReturn(false); + + bridge.log(mockSlf4JLogger, Logger.ALL, Logger.EVENT_UNSPECIFIED, testName.getMethodName()); + + Mockito.verify(mockHandler, Mockito.times(1)).isEnabled(mockSlf4JLogger); + Mockito.verify(mockScrubber, Mockito.times(0)).cleanMessage(ArgumentMatchers.anyString()); + Mockito.verify(mockHandler, Mockito.times(0)).log(ArgumentMatchers.any(org.slf4j.Logger.class), ArgumentMatchers.any(Marker.class), ArgumentMatchers.any(String.class)); + Mockito.verify(mockHandler, Mockito.times(0)).log(ArgumentMatchers.any(org.slf4j.Logger.class), ArgumentMatchers.any(Marker.class), ArgumentMatchers.any(String.class), ArgumentMatchers.any(Throwable.class)); + } + + @Test + public void testDisabledErrorLogWithException() { + Mockito.when(mockHandler.isEnabled(mockSlf4JLogger)).thenReturn(false); + + bridge.log(mockSlf4JLogger, Logger.ALL, Logger.EVENT_UNSPECIFIED, testName.getMethodName(), testEx); + + Mockito.verify(mockHandler, Mockito.times(1)).isEnabled(mockSlf4JLogger); + Mockito.verify(mockScrubber, Mockito.times(0)).cleanMessage(ArgumentMatchers.anyString()); + Mockito.verify(mockHandler, Mockito.times(0)).log(ArgumentMatchers.any(org.slf4j.Logger.class), ArgumentMatchers.any(Marker.class), ArgumentMatchers.any(String.class)); + Mockito.verify(mockHandler, Mockito.times(0)).log(ArgumentMatchers.any(org.slf4j.Logger.class), ArgumentMatchers.any(Marker.class), ArgumentMatchers.any(String.class), ArgumentMatchers.any(Throwable.class)); + + } + + + @Test + public void testNullEventTypeUsesUnspecified() { + EventType computedEventType = Logger.EVENT_UNSPECIFIED; + + //Setup for Delegate Handler + ArgumentCaptor markerCapture = ArgumentCaptor.forClass(Marker.class); + Mockito.when(mockHandler.isEnabled(mockSlf4JLogger)).thenReturn(true); + + bridge.log(mockSlf4JLogger, Logger.ALL, null, testName.getMethodName()); + + Mockito.verify(mockHandler).log(ArgumentMatchers.any(), markerCapture.capture(), ArgumentMatchers.any()); + Mockito.verify(mockAppender).appendTo(ArgumentMatchers.any(), ArgumentMatchers.eq(computedEventType), ArgumentMatchers.any()); + + Assert.assertEquals(computedEventType.toString(), markerCapture.getValue().getName()); + } + +} diff --git a/src/test/java/org/owasp/esapi/logging/slf4j/Slf4JLogFactoryTest.java b/src/test/java/org/owasp/esapi/logging/slf4j/Slf4JLogFactoryTest.java new file mode 100644 index 000000000..12a16af4c --- /dev/null +++ b/src/test/java/org/owasp/esapi/logging/slf4j/Slf4JLogFactoryTest.java @@ -0,0 +1,108 @@ +/** + * 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. + * + * @created 2018 + */ +package org.owasp.esapi.logging.slf4j; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestName; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.owasp.esapi.Logger; +import org.owasp.esapi.logging.appender.LogAppender; +import org.owasp.esapi.logging.appender.LogPrefixAppender; +import org.owasp.esapi.logging.cleaning.CodecLogScrubber; +import org.owasp.esapi.logging.cleaning.CompositeLogScrubber; +import org.owasp.esapi.logging.cleaning.LogScrubber; +import org.owasp.esapi.logging.cleaning.NewlineLogScrubber; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +@RunWith(PowerMockRunner.class) +@PrepareForTest (Slf4JLogFactory.class) +public class Slf4JLogFactoryTest { + @Rule + public TestName testName = new TestName(); + + @Test + public void testCreateLoggerByString() { + Logger logger = new Slf4JLogFactory().getLogger("test"); + Assert.assertTrue(logger instanceof Slf4JLogger); + } + + @Test public void testCreateLoggerByClass() { + Logger logger = new Slf4JLogFactory().getLogger(Slf4JLogBridgeImplTest.class); + Assert.assertTrue(logger instanceof Slf4JLogger); + } + + @Test + public void checkScrubberWithEncoding() throws Exception { + ArgumentCaptor delegates = ArgumentCaptor.forClass(List.class); + PowerMockito.whenNew(CompositeLogScrubber.class).withArguments(delegates.capture()).thenReturn(null); + + //Call to invoke the constructor capture + Slf4JLogFactory.createLogScrubber(true); + + List scrubbers = delegates.getValue(); + Assert.assertEquals(2, scrubbers.size()); + Assert.assertTrue(scrubbers.get(0) instanceof NewlineLogScrubber); + Assert.assertTrue(scrubbers.get(1) instanceof CodecLogScrubber); + } + + @Test + public void checkScrubberWithoutEncoding() throws Exception { + ArgumentCaptor delegates = ArgumentCaptor.forClass(List.class); + PowerMockito.whenNew(CompositeLogScrubber.class).withArguments(delegates.capture()).thenReturn(null); + + //Call to invoke the constructor capture + Slf4JLogFactory.createLogScrubber(false); + + List scrubbers = delegates.getValue(); + Assert.assertEquals(1, scrubbers.size()); + Assert.assertTrue(scrubbers.get(0) instanceof NewlineLogScrubber); + } + + /** + * At this time there are no special considerations or handling for the appender + * creation in this scope. It is expected that the arguments to the internal + * creation method are passed directly to the constructor of the + * LogPrefixAppender with no mutation or additional validation. + */ + @Test + public void checkPassthroughAppenderConstruct() throws Exception { + LogPrefixAppender stubAppender = new LogPrefixAppender(true, true, true, true, ""); + ArgumentCaptor userInfoCapture = ArgumentCaptor.forClass(Boolean.class); + ArgumentCaptor clientInfoCapture = ArgumentCaptor.forClass(Boolean.class); + ArgumentCaptor serverInfoCapture = ArgumentCaptor.forClass(Boolean.class); + ArgumentCaptor logAppNameCapture = ArgumentCaptor.forClass(Boolean.class); + ArgumentCaptor appNameCapture = ArgumentCaptor.forClass(String.class); + + PowerMockito.whenNew(LogPrefixAppender.class).withArguments(userInfoCapture.capture(), clientInfoCapture.capture(), serverInfoCapture.capture(), logAppNameCapture.capture(), appNameCapture.capture()).thenReturn(stubAppender); + + LogAppender appender = Slf4JLogFactory.createLogAppender(true, true, false, true, testName.getMethodName()); + + Assert.assertEquals(stubAppender, appender); + Assert.assertTrue(userInfoCapture.getValue()); + Assert.assertTrue(clientInfoCapture.getValue()); + Assert.assertFalse(serverInfoCapture.getValue()); + Assert.assertTrue(logAppNameCapture.getValue()); + Assert.assertEquals(testName.getMethodName(), appNameCapture.getValue()); + } + + +} diff --git a/src/test/java/org/owasp/esapi/logging/slf4j/Slf4JLogLevelHandlersTest.java b/src/test/java/org/owasp/esapi/logging/slf4j/Slf4JLogLevelHandlersTest.java new file mode 100644 index 000000000..73e4833ba --- /dev/null +++ b/src/test/java/org/owasp/esapi/logging/slf4j/Slf4JLogLevelHandlersTest.java @@ -0,0 +1,90 @@ +/** + * 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. + * + * @created 2018 + */ +package org.owasp.esapi.logging.slf4j; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestName; +import org.mockito.Mockito; +import org.slf4j.Logger; +import org.slf4j.Marker; +import org.slf4j.helpers.BasicMarkerFactory; + +public class Slf4JLogLevelHandlersTest { + + private Logger mockLogger = Mockito.mock(Logger.class); + @Rule + public TestName testName = new TestName(); + + private Marker marker = new BasicMarkerFactory().getMarker(Slf4JLogLevelHandlersTest.class.getSimpleName()); + private Throwable testException = new Throwable("Expected for testing"); + + @Test + public void testErrorDelegation() { + Slf4JLogLevelHandlers.ERROR.isEnabled(mockLogger); + Slf4JLogLevelHandlers.ERROR.log(mockLogger, marker, testName.getMethodName()); + Slf4JLogLevelHandlers.ERROR.log(mockLogger, marker, testName.getMethodName(), testException); + + Mockito.verify(mockLogger, Mockito.times(1)).isErrorEnabled(); + Mockito.verify(mockLogger, Mockito.times(1)).error(marker, testName.getMethodName()); + Mockito.verify(mockLogger, Mockito.times(1)).error(marker, testName.getMethodName(), testException); + Mockito.verifyNoMoreInteractions(mockLogger); + } + + @Test + public void testWarnDelegation() { + Slf4JLogLevelHandlers.WARN.isEnabled(mockLogger); + Slf4JLogLevelHandlers.WARN.log(mockLogger, marker, testName.getMethodName()); + Slf4JLogLevelHandlers.WARN.log(mockLogger, marker, testName.getMethodName(), testException); + + Mockito.verify(mockLogger, Mockito.times(1)).isWarnEnabled(); + Mockito.verify(mockLogger, Mockito.times(1)).warn(marker, testName.getMethodName()); + Mockito.verify(mockLogger, Mockito.times(1)).warn(marker, testName.getMethodName(), testException); + Mockito.verifyNoMoreInteractions(mockLogger); + } + @Test + public void testInfoDelegation() { + Slf4JLogLevelHandlers.INFO.isEnabled(mockLogger); + Slf4JLogLevelHandlers.INFO.log(mockLogger, marker, testName.getMethodName()); + Slf4JLogLevelHandlers.INFO.log(mockLogger, marker, testName.getMethodName(), testException); + + Mockito.verify(mockLogger, Mockito.times(1)).isInfoEnabled(); + Mockito.verify(mockLogger, Mockito.times(1)).info(marker, testName.getMethodName()); + Mockito.verify(mockLogger, Mockito.times(1)).info(marker, testName.getMethodName(), testException); + Mockito.verifyNoMoreInteractions(mockLogger); + } + @Test + public void testDebugDelegation() { + Slf4JLogLevelHandlers.DEBUG.isEnabled(mockLogger); + Slf4JLogLevelHandlers.DEBUG.log(mockLogger, marker, testName.getMethodName()); + Slf4JLogLevelHandlers.DEBUG.log(mockLogger, marker, testName.getMethodName(), testException); + + Mockito.verify(mockLogger, Mockito.times(1)).isDebugEnabled(); + Mockito.verify(mockLogger, Mockito.times(1)).debug(marker, testName.getMethodName()); + Mockito.verify(mockLogger, Mockito.times(1)).debug(marker, testName.getMethodName(), testException); + Mockito.verifyNoMoreInteractions(mockLogger); + } + @Test + public void testTraceDelegation() { + Slf4JLogLevelHandlers.TRACE.isEnabled(mockLogger); + Slf4JLogLevelHandlers.TRACE.log(mockLogger, marker, testName.getMethodName()); + Slf4JLogLevelHandlers.TRACE.log(mockLogger, marker, testName.getMethodName(), testException); + + Mockito.verify(mockLogger, Mockito.times(1)).isTraceEnabled(); + Mockito.verify(mockLogger, Mockito.times(1)).trace(marker, testName.getMethodName()); + Mockito.verify(mockLogger, Mockito.times(1)).trace(marker, testName.getMethodName(), testException); + Mockito.verifyNoMoreInteractions(mockLogger); + } +} diff --git a/src/test/java/org/owasp/esapi/logging/slf4j/Slf4JLoggerTest.java b/src/test/java/org/owasp/esapi/logging/slf4j/Slf4JLoggerTest.java new file mode 100644 index 000000000..77e718d34 --- /dev/null +++ b/src/test/java/org/owasp/esapi/logging/slf4j/Slf4JLoggerTest.java @@ -0,0 +1,285 @@ +/** + * 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. + * + * @created 2018 + */ + +package org.owasp.esapi.logging.slf4j; + +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; +import org.owasp.esapi.Logger; + +public class Slf4JLoggerTest { + + private static final String MSG = Slf4JLoggerTest.class.getSimpleName(); + + private Slf4JLogBridge mockBridge = Mockito.mock(Slf4JLogBridge.class); + private org.slf4j.Logger mockLogDelegate = Mockito.mock(org.slf4j.Logger.class); + + private Throwable testEx = new Throwable(MSG + "_Exception"); + private Logger testLogger = new Slf4JLogger(mockLogDelegate, mockBridge, Logger.ALL); + + @Test + public void testLevelEnablement() { + testLogger.setLevel(Logger.INFO); + + Assert.assertTrue(testLogger.isFatalEnabled()); + Assert.assertTrue(testLogger.isErrorEnabled()); + Assert.assertTrue(testLogger.isWarningEnabled()); + Assert.assertTrue(testLogger.isInfoEnabled()); + Assert.assertFalse(testLogger.isDebugEnabled()); + Assert.assertFalse(testLogger.isTraceEnabled()); + + Assert.assertEquals(Logger.INFO, testLogger.getESAPILevel()); + } + + @Test + public void testAllLevelEnablement() { + testLogger.setLevel(Logger.ALL); + + Assert.assertTrue(testLogger.isFatalEnabled()); + Assert.assertTrue(testLogger.isErrorEnabled()); + Assert.assertTrue(testLogger.isWarningEnabled()); + Assert.assertTrue(testLogger.isInfoEnabled()); + Assert.assertTrue(testLogger.isDebugEnabled()); + Assert.assertTrue(testLogger.isTraceEnabled()); + } + + @Test + public void testOffLevelEnablement() { + testLogger.setLevel(Logger.OFF); + + Assert.assertFalse(testLogger.isFatalEnabled()); + Assert.assertFalse(testLogger.isErrorEnabled()); + Assert.assertFalse(testLogger.isWarningEnabled()); + Assert.assertFalse(testLogger.isInfoEnabled()); + Assert.assertFalse(testLogger.isDebugEnabled()); + Assert.assertFalse(testLogger.isTraceEnabled()); + } + @Test + public void testFatalWithMessage() { + testLogger.fatal(Logger.EVENT_UNSPECIFIED, MSG); + + Mockito.verify(mockBridge, Mockito.times(1)).log(mockLogDelegate, Logger.FATAL, Logger.EVENT_UNSPECIFIED, MSG); + Mockito.verifyNoMoreInteractions(mockBridge, mockLogDelegate); + } + @Test + public void testFatalWithMessageAndThrowable() { + testLogger.fatal(Logger.EVENT_UNSPECIFIED, MSG, testEx); + + Mockito.verify(mockBridge, Mockito.times(1)).log(mockLogDelegate, Logger.FATAL, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, mockLogDelegate); + } + + @Test + public void testFatalWithMessageDisabled() { + testLogger.setLevel(Logger.OFF); + testLogger.fatal(Logger.EVENT_UNSPECIFIED, MSG); + + Mockito.verify(mockBridge, Mockito.times(0)).log(mockLogDelegate, Logger.FATAL, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, mockLogDelegate); + } + @Test + public void testFatalWithMessageAndThrowableDisabled() { + testLogger.setLevel(Logger.OFF); + testLogger.fatal(Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verify(mockBridge, Mockito.times(0)).log(mockLogDelegate, Logger.FATAL, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, mockLogDelegate); + } + + @Test + public void testErrorWithMessage() { + testLogger.error(Logger.EVENT_UNSPECIFIED, MSG); + + Mockito.verify(mockBridge, Mockito.times(1)).log(mockLogDelegate, Logger.ERROR, Logger.EVENT_UNSPECIFIED, MSG); + Mockito.verifyNoMoreInteractions(mockBridge, mockLogDelegate); + } + @Test + public void testErrorWithMessageAndThrowable() { + testLogger.error(Logger.EVENT_UNSPECIFIED, MSG, testEx); + + Mockito.verify(mockBridge, Mockito.times(1)).log(mockLogDelegate, Logger.ERROR, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, mockLogDelegate); + } + + @Test + public void testErrorWithMessageDisabled() { + testLogger.setLevel(Logger.OFF); + testLogger.error(Logger.EVENT_UNSPECIFIED, MSG); + + Mockito.verify(mockBridge, Mockito.times(0)).log(mockLogDelegate, Logger.ERROR, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, mockLogDelegate); + } + @Test + public void testErrorWithMessageAndThrowableDisabled() { + testLogger.setLevel(Logger.OFF); + testLogger.error(Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verify(mockBridge, Mockito.times(0)).log(mockLogDelegate, Logger.ERROR, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, mockLogDelegate); + } + + @Test + public void testWarnWithMessage() { + testLogger.warning(Logger.EVENT_UNSPECIFIED, MSG); + + Mockito.verify(mockBridge, Mockito.times(1)).log(mockLogDelegate, Logger.WARNING, Logger.EVENT_UNSPECIFIED, MSG); + Mockito.verifyNoMoreInteractions(mockBridge, mockLogDelegate); + } + @Test + public void testWarnWithMessageAndThrowable() { + testLogger.warning(Logger.EVENT_UNSPECIFIED, MSG, testEx); + + Mockito.verify(mockBridge, Mockito.times(1)).log(mockLogDelegate, Logger.WARNING, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, mockLogDelegate); + } + + @Test + public void testWarnWithMessageDisabled() { + testLogger.setLevel(Logger.OFF); + testLogger.warning(Logger.EVENT_UNSPECIFIED, MSG); + + Mockito.verify(mockBridge, Mockito.times(0)).log(mockLogDelegate, Logger.WARNING, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, mockLogDelegate); + } + @Test + public void testWarnWithMessageAndThrowableDisabled() { + testLogger.setLevel(Logger.OFF); + testLogger.warning(Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verify(mockBridge, Mockito.times(0)).log(mockLogDelegate, Logger.WARNING, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, mockLogDelegate); + } + + @Test + public void testInfoWithMessage() { + testLogger.info(Logger.EVENT_UNSPECIFIED, MSG); + + Mockito.verify(mockBridge, Mockito.times(1)).log(mockLogDelegate, Logger.INFO, Logger.EVENT_UNSPECIFIED, MSG); + Mockito.verifyNoMoreInteractions(mockBridge, mockLogDelegate); + } + @Test + public void testInfoWithMessageAndThrowable() { + testLogger.info(Logger.EVENT_UNSPECIFIED, MSG, testEx); + + Mockito.verify(mockBridge, Mockito.times(1)).log(mockLogDelegate, Logger.INFO, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, mockLogDelegate); + } + + @Test + public void testInfoWithMessageDisabled() { + testLogger.setLevel(Logger.OFF); + testLogger.info(Logger.EVENT_UNSPECIFIED, MSG); + + Mockito.verify(mockBridge, Mockito.times(0)).log(mockLogDelegate, Logger.INFO, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, mockLogDelegate); + } + @Test + public void testInfoWithMessageAndThrowableDisabled() { + testLogger.setLevel(Logger.OFF); + testLogger.info(Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verify(mockBridge, Mockito.times(0)).log(mockLogDelegate, Logger.INFO, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, mockLogDelegate); + } + @Test + public void testDebugWithMessage() { + testLogger.debug(Logger.EVENT_UNSPECIFIED, MSG); + + Mockito.verify(mockBridge, Mockito.times(1)).log(mockLogDelegate, Logger.DEBUG, Logger.EVENT_UNSPECIFIED, MSG); + Mockito.verifyNoMoreInteractions(mockBridge, mockLogDelegate); + } + @Test + public void testDebugWithMessageAndThrowable() { + testLogger.debug(Logger.EVENT_UNSPECIFIED, MSG, testEx); + + Mockito.verify(mockBridge, Mockito.times(1)).log(mockLogDelegate, Logger.DEBUG, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, mockLogDelegate); + } + + @Test + public void testDebugWithMessageDisabled() { + testLogger.setLevel(Logger.OFF); + testLogger.debug(Logger.EVENT_UNSPECIFIED, MSG); + + Mockito.verify(mockBridge, Mockito.times(0)).log(mockLogDelegate, Logger.DEBUG, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, mockLogDelegate); + } + @Test + public void testDebugWithMessageAndThrowableDisabled() { + testLogger.setLevel(Logger.OFF); + testLogger.debug(Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verify(mockBridge, Mockito.times(0)).log(mockLogDelegate, Logger.DEBUG, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, mockLogDelegate); + } + + @Test + public void testTraceWithMessage() { + testLogger.trace(Logger.EVENT_UNSPECIFIED, MSG); + + Mockito.verify(mockBridge, Mockito.times(1)).log(mockLogDelegate, Logger.TRACE, Logger.EVENT_UNSPECIFIED, MSG); + Mockito.verifyNoMoreInteractions(mockBridge, mockLogDelegate); + } + @Test + public void testTraceWithMessageAndThrowable() { + testLogger.trace(Logger.EVENT_UNSPECIFIED, MSG, testEx); + + Mockito.verify(mockBridge, Mockito.times(1)).log(mockLogDelegate, Logger.TRACE, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, mockLogDelegate); + } + + @Test + public void testTraceWithMessageDisabled() { + testLogger.setLevel(Logger.OFF); + testLogger.trace(Logger.EVENT_UNSPECIFIED, MSG); + + Mockito.verify(mockBridge, Mockito.times(0)).log(mockLogDelegate, Logger.TRACE, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, mockLogDelegate); + } + @Test + public void testTraceWithMessageAndThrowableDisabled() { + testLogger.setLevel(Logger.OFF); + testLogger.trace(Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verify(mockBridge, Mockito.times(0)).log(mockLogDelegate, Logger.TRACE, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, mockLogDelegate); + } + + @Test + public void testAlwaysWithMessage() { + testLogger.always(Logger.EVENT_UNSPECIFIED, MSG); + + Mockito.verify(mockBridge, Mockito.times(1)).log(mockLogDelegate, Logger.ALL, Logger.EVENT_UNSPECIFIED, MSG); + Mockito.verifyNoMoreInteractions(mockBridge, mockLogDelegate); + } + @Test + public void testAlwaysWithMessageAndThrowable() { + testLogger.always(Logger.EVENT_UNSPECIFIED, MSG, testEx); + + Mockito.verify(mockBridge, Mockito.times(1)).log(mockLogDelegate, Logger.ALL, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, mockLogDelegate); + } + + @Test + public void testAlwaysWithMessageDisabled() { + testLogger.setLevel(Logger.OFF); + testLogger.always(Logger.EVENT_UNSPECIFIED, MSG); + + Mockito.verify(mockBridge, Mockito.times(0)).log(mockLogDelegate, Logger.ALL, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, mockLogDelegate); + } + @Test + public void testAlwaysWithMessageAndThrowableDisabled() { + testLogger.setLevel(Logger.OFF); + testLogger.always(Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verify(mockBridge, Mockito.times(0)).log(mockLogDelegate, Logger.ALL, Logger.EVENT_UNSPECIFIED, MSG, testEx); + Mockito.verifyNoMoreInteractions(mockBridge, mockLogDelegate); + } +} diff --git a/src/test/java/org/owasp/esapi/reference/AbstractAccessReferenceMapTest.java b/src/test/java/org/owasp/esapi/reference/AbstractAccessReferenceMapTest.java new file mode 100644 index 000000000..3d7836210 --- /dev/null +++ b/src/test/java/org/owasp/esapi/reference/AbstractAccessReferenceMapTest.java @@ -0,0 +1,100 @@ +package org.owasp.esapi.reference; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; + +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; +import org.powermock.reflect.Whitebox; + + +public class AbstractAccessReferenceMapTest { + + @Test + public void testConcurrentAddDirectReference() throws Exception { + @SuppressWarnings("unchecked") + final AbstractAccessReferenceMap map = Mockito.mock(AbstractAccessReferenceMap.class, Mockito.withSettings().useConstructor() + .defaultAnswer(Mockito.CALLS_REAL_METHODS) + ); + Object indirectObj = new Object(); + Mockito.when(map.getUniqueReference()).thenReturn(indirectObj); + + final HashMap itod= Whitebox.getInternalState(map, "itod"); + + final Object toAdd = new Object(); + + Runnable addReference1 = new Runnable() { + @Override + public void run() { + map.addDirectReference(toAdd); + } + }; + Runnable addReference2 = new Runnable() { + @Override + public void run() { + map.addDirectReference(toAdd); + } + }; + + Runnable lockItod = new Runnable() { + public void run() { + synchronized (itod) { + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + } + }; + + Thread lockIndirectRefs = new Thread(lockItod, "Lock Indirect Refs"); + Thread addRef1Thread = new Thread(addReference1, "Add Ref 1"); + Thread addRef2Thread = new Thread(addReference2, "Add Ref 2"); + lockIndirectRefs.start(); + addRef1Thread.start(); + addRef2Thread.start(); + + addRef1Thread.join(); + addRef2Thread.join(); + lockIndirectRefs.join(); + + Mockito.verify(map,Mockito.times(1)).getUniqueReference(); + } + + @Test + public void verifyNoDuplicateKeysOnUpdateReplace() { + @SuppressWarnings("unchecked") + final AbstractAccessReferenceMap map = Mockito.mock(AbstractAccessReferenceMap.class, Mockito.withSettings().useConstructor() + .defaultAnswer(Mockito.CALLS_REAL_METHODS) + ); + Object indirectObj1 = new Object(); + Object indirectObj2 = new Object(); + Mockito.when(map.getUniqueReference()).thenReturn(indirectObj1); + + Object direct1 = new Object(); + Object direct2 = new Object(); + + map.addDirectReference(direct1); + + Mockito.reset(map); + + Set newDirectElements = new HashSet<>(); + newDirectElements.add(direct2); + newDirectElements.add(direct1); + + Mockito.when(map.getUniqueReference()).thenReturn(indirectObj1).thenReturn(indirectObj2); + + map.update(newDirectElements); + + //Needs to be called 2 times to get past the first duplicate key. This verifies that we're inserting unique pairs. + Mockito.verify(map, Mockito.times(2)).getUniqueReference(); + + Assert.assertEquals(indirectObj1, map.getIndirectReference(direct1)); + Assert.assertEquals(indirectObj2, map.getIndirectReference(direct2)); + } +} diff --git a/src/test/java/org/owasp/esapi/reference/AccessControllerTest.java b/src/test/java/org/owasp/esapi/reference/AccessControllerTest.java new file mode 100644 index 000000000..a2c20c2e5 --- /dev/null +++ b/src/test/java/org/owasp/esapi/reference/AccessControllerTest.java @@ -0,0 +1,358 @@ +/** + * 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.reference; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.AccessController; +import org.owasp.esapi.Authenticator; +import org.owasp.esapi.User; +import org.owasp.esapi.errors.AccessControlException; + + +/** + * The Class AccessControllerTest. + * + * @author Jeff Williams (jeff.williams@aspectsecurity.com) + */ +public class AccessControllerTest extends TestCase { + + /** + * Instantiates a new access controller test. + * + * @param testName + * the test name + * @throws Exception + */ + public AccessControllerTest(String testName) throws Exception { + super(testName); + + Authenticator authenticator = ESAPI.authenticator(); + String password = authenticator.generateStrongPassword(); + + // create a user with the "user" role for this test + User alice = authenticator.getUser("testuser1"); + if ( alice == null ) { + alice = authenticator.createUser( "testuser1", password, password); + } + alice.addRole("user"); + + // create a user with the "admin" role for this test + User bob = authenticator.getUser("testuser2"); + if ( bob == null ) { + bob = authenticator.createUser( "testuser2", password, password); + } + bob.addRole("admin"); + + // create a user with the "user" and "admin" roles for this test + User mitch = authenticator.getUser("testuser3"); + if ( mitch == null ) { + mitch = authenticator.createUser( "testuser3", password, password); + } + mitch.addRole("admin"); + mitch.addRole("user"); + } + + /** + * {@inheritDoc} + * + * @throws Exception + */ + protected void setUp() throws Exception { + } + + /** + * {@inheritDoc} + * + * @throws Exception + */ + protected void tearDown() throws Exception { + // none + } + + /** + * Suite. + * + * @return the test + */ + public static Test suite() { + TestSuite suite = new TestSuite(AccessControllerTest.class); + return suite; + } + + /** + * + */ + public void testMatchRule() { + ESAPI.authenticator().setCurrentUser(null); + assertFalse(ESAPI.accessController().isAuthorizedForURL("/nobody")); + } + + /** + * Test of isAuthorizedForURL method, of class + * org.owasp.esapi.AccessController. + * + * @throws Exception + */ + public void testIsAuthorizedForURL() throws Exception { + System.out.println("isAuthorizedForURL"); + AccessController instance = ESAPI.accessController(); + Authenticator auth = ESAPI.authenticator(); + + auth.setCurrentUser( auth.getUser("testuser1") ); + assertFalse(instance.isAuthorizedForURL("/nobody")); + assertFalse(instance.isAuthorizedForURL("/test/admin")); + assertTrue(instance.isAuthorizedForURL("/test/user")); + assertTrue(instance.isAuthorizedForURL("/test/all")); + assertFalse(instance.isAuthorizedForURL("/test/none")); + assertTrue(instance.isAuthorizedForURL("/test/none/test.gif")); + assertFalse(instance.isAuthorizedForURL("/test/none/test.exe")); + assertTrue(instance.isAuthorizedForURL("/test/none/test.png")); + assertFalse(instance.isAuthorizedForURL("/test/moderator")); + assertTrue(instance.isAuthorizedForURL("/test/profile")); + assertFalse(instance.isAuthorizedForURL("/upload")); + + auth.setCurrentUser( auth.getUser("testuser2") ); + assertFalse(instance.isAuthorizedForURL("/nobody")); + assertTrue(instance.isAuthorizedForURL("/test/admin")); + assertFalse(instance.isAuthorizedForURL("/test/user")); + assertTrue(instance.isAuthorizedForURL("/test/all")); + assertFalse(instance.isAuthorizedForURL("/test/none")); + assertTrue(instance.isAuthorizedForURL("/test/none/test.png")); + assertFalse(instance.isAuthorizedForURL("/test/moderator")); + assertTrue(instance.isAuthorizedForURL("/test/profile")); + assertFalse(instance.isAuthorizedForURL("/upload")); + + auth.setCurrentUser( auth.getUser("testuser3") ); + assertFalse(instance.isAuthorizedForURL("/nobody")); + assertTrue(instance.isAuthorizedForURL("/test/admin")); + assertTrue(instance.isAuthorizedForURL("/test/user")); + assertTrue(instance.isAuthorizedForURL("/test/all")); + assertFalse(instance.isAuthorizedForURL("/test/none")); + assertTrue(instance.isAuthorizedForURL("/test/none/test.png")); + assertFalse(instance.isAuthorizedForURL("/test/moderator")); + assertTrue(instance.isAuthorizedForURL("/test/profile")); + assertFalse(instance.isAuthorizedForURL("/upload")); + + try { + instance.assertAuthorizedForURL("/test/admin"); + instance.assertAuthorizedForURL( "/nobody" ); + fail(); + } catch ( AccessControlException e ) { + // expected + } + } + + /** + * Test of isAuthorizedForFunction method, of class + * org.owasp.esapi.AccessController. + */ + public void testIsAuthorizedForFunction() { + System.out.println("isAuthorizedForFunction"); + AccessController instance = ESAPI.accessController(); + Authenticator auth = ESAPI.authenticator(); + + auth.setCurrentUser( auth.getUser("testuser1") ); + assertTrue(instance.isAuthorizedForFunction("/FunctionA")); + assertFalse(instance.isAuthorizedForFunction("/FunctionAdeny")); + assertFalse(instance.isAuthorizedForFunction("/FunctionB")); + assertFalse(instance.isAuthorizedForFunction("/FunctionBdeny")); + assertTrue(instance.isAuthorizedForFunction("/FunctionC")); + assertFalse(instance.isAuthorizedForFunction("/FunctionCdeny")); + + auth.setCurrentUser( auth.getUser("testuser2") ); + assertFalse(instance.isAuthorizedForFunction("/FunctionA")); + assertFalse(instance.isAuthorizedForFunction("/FunctionAdeny")); + assertTrue(instance.isAuthorizedForFunction("/FunctionB")); + assertFalse(instance.isAuthorizedForFunction("/FunctionBdeny")); + assertTrue(instance.isAuthorizedForFunction("/FunctionD")); + assertFalse(instance.isAuthorizedForFunction("/FunctionDdeny")); + + auth.setCurrentUser( auth.getUser("testuser3") ); + assertTrue(instance.isAuthorizedForFunction("/FunctionA")); + assertFalse(instance.isAuthorizedForFunction("/FunctionAdeny")); + assertTrue(instance.isAuthorizedForFunction("/FunctionB")); + assertFalse(instance.isAuthorizedForFunction("/FunctionBdeny")); + assertTrue(instance.isAuthorizedForFunction("/FunctionC")); + assertFalse(instance.isAuthorizedForFunction("/FunctionCdeny")); + + try { + instance.assertAuthorizedForFunction("/FunctionA"); + instance.assertAuthorizedForFunction( "/FunctionDdeny" ); + fail(); + } catch ( AccessControlException e ) { + // expected + } + } + + /** + * Test of isAuthorizedForData method, of class + * org.owasp.esapi.AccessController. + */ + public void testIsAuthorizedForData() { + System.out.println("isAuthorizedForData"); + AccessController instance = ESAPI.accessController(); + Authenticator auth = ESAPI.authenticator(); + + Class adminR = null; + Class adminRW = null; + Class userW = null; + Class userRW = null; + Class anyR = null; + Class userAdminR = null; + Class userAdminRW = null; + Class undefined = null; + + try{ + adminR = Class.forName("java.util.ArrayList"); + adminRW = Class.forName("java.lang.Math"); + userW = Class.forName("java.util.Date"); + userRW = Class.forName("java.lang.String"); + anyR = Class.forName("java.io.BufferedReader"); + userAdminR = Class.forName("java.util.Random"); + userAdminRW = Class.forName("javax.crypto.Cipher"); + undefined = Class.forName("java.io.FileWriter"); + + }catch(ClassNotFoundException cnf){ + System.out.println("CLASS NOT FOUND."); + cnf.printStackTrace(); + } + //test User + auth.setCurrentUser( auth.getUser("testuser1") ); + assertTrue(instance.isAuthorizedForData("read", userRW)); + assertFalse(instance.isAuthorizedForData("read", undefined)); + assertFalse(instance.isAuthorizedForData("write", undefined)); + assertFalse(instance.isAuthorizedForData("read", userW)); + assertFalse(instance.isAuthorizedForData("read", adminRW)); + assertTrue(instance.isAuthorizedForData("write", userRW)); + assertTrue(instance.isAuthorizedForData("write", userW)); + assertFalse(instance.isAuthorizedForData("write", anyR)); + assertTrue(instance.isAuthorizedForData("read", anyR)); + assertTrue(instance.isAuthorizedForData("read", userAdminR)); + assertTrue(instance.isAuthorizedForData("write", userAdminRW)); + + //test Admin + auth.setCurrentUser( auth.getUser("testuser2") ); + assertTrue(instance.isAuthorizedForData("read", adminRW)); + assertFalse(instance.isAuthorizedForData("read", undefined)); + assertFalse(instance.isAuthorizedForData("write", undefined)); + assertFalse(instance.isAuthorizedForData("read", userRW)); + assertTrue(instance.isAuthorizedForData("write", adminRW)); + assertFalse(instance.isAuthorizedForData("write", anyR)); + assertTrue(instance.isAuthorizedForData("read", anyR)); + assertTrue(instance.isAuthorizedForData("read", userAdminR)); + assertTrue(instance.isAuthorizedForData("write", userAdminRW)); + + //test User/Admin + auth.setCurrentUser( auth.getUser("testuser3") ); + assertTrue(instance.isAuthorizedForData("read", userRW)); + assertFalse(instance.isAuthorizedForData("read", undefined)); + assertFalse(instance.isAuthorizedForData("write", undefined)); + assertFalse(instance.isAuthorizedForData("read", userW)); + assertTrue(instance.isAuthorizedForData("read", adminR)); + assertTrue(instance.isAuthorizedForData("write", userRW)); + assertTrue(instance.isAuthorizedForData("write", userW)); + assertFalse(instance.isAuthorizedForData("write", anyR)); + assertTrue(instance.isAuthorizedForData("read", anyR)); + assertTrue(instance.isAuthorizedForData("read", userAdminR)); + assertTrue(instance.isAuthorizedForData("write", userAdminRW)); + try { + instance.assertAuthorizedForData("read", userRW); + instance.assertAuthorizedForData( "write", adminR ); + fail(); + } catch ( AccessControlException e ) { + // expected + } + + } + + /** + * Test of isAuthorizedForFile method, of class + * org.owasp.esapi.AccessController. + */ + public void testIsAuthorizedForFile() { + System.out.println("isAuthorizedForFile"); + AccessController instance = ESAPI.accessController(); + Authenticator auth = ESAPI.authenticator(); + + auth.setCurrentUser( auth.getUser("testuser1") ); + assertTrue(instance.isAuthorizedForFile("/Dir/File1")); + assertFalse(instance.isAuthorizedForFile("/Dir/File2")); + assertTrue(instance.isAuthorizedForFile("/Dir/File3")); + assertFalse(instance.isAuthorizedForFile("/Dir/ridiculous")); + + auth.setCurrentUser( auth.getUser("testuser2") ); + assertFalse(instance.isAuthorizedForFile("/Dir/File1")); + assertTrue(instance.isAuthorizedForFile("/Dir/File2")); + assertTrue(instance.isAuthorizedForFile("/Dir/File4")); + assertFalse(instance.isAuthorizedForFile("/Dir/ridiculous")); + + auth.setCurrentUser( auth.getUser("testuser3") ); + assertTrue(instance.isAuthorizedForFile("/Dir/File1")); + assertTrue(instance.isAuthorizedForFile("/Dir/File2")); + assertFalse(instance.isAuthorizedForFile("/Dir/File5")); + assertFalse(instance.isAuthorizedForFile("/Dir/ridiculous")); + + try { + instance.assertAuthorizedForFile("/Dir/File1"); + instance.assertAuthorizedForFile( "/Dir/File6" ); + fail(); + } catch ( AccessControlException e ) { + // expected + } + } + + /** + * Test of isAuthorizedForService method, of class + * org.owasp.esapi.AccessController. + */ + public void testIsAuthorizedForService() { + System.out.println("isAuthorizedForService"); + AccessController instance = ESAPI.accessController(); + Authenticator auth = ESAPI.authenticator(); + + auth.setCurrentUser( auth.getUser("testuser1") ); + assertTrue(instance.isAuthorizedForService("/services/ServiceA")); + assertFalse(instance.isAuthorizedForService("/services/ServiceB")); + assertTrue(instance.isAuthorizedForService("/services/ServiceC")); + + assertFalse(instance.isAuthorizedForService("/test/ridiculous")); + + auth.setCurrentUser( auth.getUser("testuser2") ); + assertFalse(instance.isAuthorizedForService("/services/ServiceA")); + assertTrue(instance.isAuthorizedForService("/services/ServiceB")); + assertFalse(instance.isAuthorizedForService("/services/ServiceF")); + assertFalse(instance.isAuthorizedForService("/test/ridiculous")); + + auth.setCurrentUser( auth.getUser("testuser3") ); + assertTrue(instance.isAuthorizedForService("/services/ServiceA")); + assertTrue(instance.isAuthorizedForService("/services/ServiceB")); + assertFalse(instance.isAuthorizedForService("/services/ServiceE")); + assertFalse(instance.isAuthorizedForService("/test/ridiculous")); + + try { + instance.assertAuthorizedForService("/services/ServiceD"); + instance.assertAuthorizedForService( "/test/ridiculous" ); + fail(); + } catch ( AccessControlException e ) { + // expected + } + } + +} diff --git a/src/test/java/org/owasp/esapi/reference/AccessReferenceMapTest.java b/src/test/java/org/owasp/esapi/reference/AccessReferenceMapTest.java new file mode 100644 index 000000000..f04655fb3 --- /dev/null +++ b/src/test/java/org/owasp/esapi/reference/AccessReferenceMapTest.java @@ -0,0 +1,223 @@ +/** + * 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.reference; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.owasp.esapi.Authenticator; +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.User; +import org.owasp.esapi.errors.AccessControlException; +import org.owasp.esapi.errors.AuthenticationException; +import org.owasp.esapi.errors.EncryptionException; + + +/** + * The Class AccessReferenceMapTest. + * + * @author Jeff Williams (jeff.williams@aspectsecurity.com) + */ +public class AccessReferenceMapTest extends TestCase { + + /** + * Instantiates a new access reference map test. + * + * @param testName + * the test name + */ + public AccessReferenceMapTest(String testName) { + super(testName); + } + + /** + * {@inheritDoc} + * @throws Exception + */ + protected void setUp() throws Exception { + // none + } + + /** + * {@inheritDoc} + * @throws Exception + */ + protected void tearDown() throws Exception { + // none + } + + /** + * Suite. + * + * @return the test + */ + public static Test suite() { + TestSuite suite = new TestSuite(AccessReferenceMapTest.class); + return suite; + } + + + /** + * Test of update method, of class org.owasp.esapi.AccessReferenceMap. + * + * @throws AuthenticationException + * the authentication exception + * @throws EncryptionException + */ + public void testUpdate() throws AuthenticationException, EncryptionException { + System.out.println("update"); + RandomAccessReferenceMap arm = new RandomAccessReferenceMap(); + Authenticator auth = ESAPI.authenticator(); + + String pass = auth.generateStrongPassword(); + User u = auth.createUser( "armUpdate", pass, pass ); + + // test to make sure update returns something + arm.update(auth.getUserNames()); + String indirect = arm.getIndirectReference( u.getAccountName() ); + if ( indirect == null ) fail(); + + // test to make sure update removes items that are no longer in the list + auth.removeUser( u.getAccountName() ); + arm.update(auth.getUserNames()); + indirect = arm.getIndirectReference( u.getAccountName() ); + if ( indirect != null ) fail(); + + // test to make sure old indirect reference is maintained after an update + arm.update(auth.getUserNames()); + String newIndirect = arm.getIndirectReference( u.getAccountName() ); + assertEquals(indirect, newIndirect); + } + + + /** + * Test of iterator method, of class org.owasp.esapi.AccessReferenceMap. + */ + public void testIterator() { + System.out.println("iterator"); + RandomAccessReferenceMap arm = new RandomAccessReferenceMap(); + Authenticator auth = ESAPI.authenticator(); + + arm.update(auth.getUserNames()); + + Iterator i = arm.iterator(); + while ( i.hasNext() ) { + String userName = (String)i.next(); + User u = auth.getUser( userName ); + if ( u == null ) fail(); + } + } + + /** + * Test of getIndirectReference method, of class + * org.owasp.esapi.AccessReferenceMap. + */ + public void testGetIndirectReference() { + System.out.println("getIndirectReference"); + + String directReference = "234"; + Set list = new HashSet(); + list.add( "123" ); + list.add( directReference ); + list.add( "345" ); + RandomAccessReferenceMap instance = new RandomAccessReferenceMap( list ); + + String expResult = directReference; + String result = instance.getIndirectReference(directReference); + assertNotSame(expResult, result); + } + + /** + * Test of getDirectReference method, of class + * org.owasp.esapi.AccessReferenceMap. + * + * @throws AccessControlException + * the access control exception + */ + public void testGetDirectReference() throws AccessControlException { + System.out.println("getDirectReference"); + + String directReference = "234"; + Set list = new HashSet(); + list.add( "123" ); + list.add( directReference ); + list.add( "345" ); + RandomAccessReferenceMap instance = new RandomAccessReferenceMap( list ); + + String ind = instance.getIndirectReference(directReference); + String dir = (String)instance.getDirectReference(ind); + assertEquals(directReference, dir); + try { + instance.getDirectReference("invalid"); + fail(); + } catch( AccessControlException e ) { + // success + } + } + + /** + * + * @throws org.owasp.esapi.errors.AccessControlException + */ + public void testAddDirectReference() throws AccessControlException { + System.out.println("addDirectReference"); + + String directReference = "234"; + Set list = new HashSet(); + list.add( "123" ); + list.add( directReference ); + list.add( "345" ); + RandomAccessReferenceMap instance = new RandomAccessReferenceMap( list ); + + String newDirect = instance.addDirectReference("newDirect"); + assertNotNull( newDirect ); + String ind = instance.addDirectReference(directReference); + String dir = (String)instance.getDirectReference(ind); + assertEquals(directReference, dir); + String newInd = instance.addDirectReference(directReference); + assertEquals(ind, newInd); + } + + /** + * + * @throws org.owasp.esapi.errors.AccessControlException + */ + public void testRemoveDirectReference() throws AccessControlException { + System.out.println("removeDirectReference"); + + String directReference = "234"; + Set list = new HashSet(); + list.add( "123" ); + list.add( directReference ); + list.add( "345" ); + RandomAccessReferenceMap instance = new RandomAccessReferenceMap( list ); + + String indirect = instance.getIndirectReference(directReference); + assertNotNull(indirect); + String deleted = instance.removeDirectReference(directReference); + assertEquals(indirect,deleted); + deleted = instance.removeDirectReference("ridiculous"); + assertNull(deleted); + } + + + +} diff --git a/src/test/java/org/owasp/esapi/reference/AuthenticatorTest.java b/src/test/java/org/owasp/esapi/reference/AuthenticatorTest.java new file mode 100644 index 000000000..5df1b5c5b --- /dev/null +++ b/src/test/java/org/owasp/esapi/reference/AuthenticatorTest.java @@ -0,0 +1,697 @@ +/** + * 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.reference; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.junit.Assume.assumeTrue; + +import java.util.Calendar; +import java.util.Set; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.hamcrest.core.IsEqual; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ErrorCollector; +import org.junit.rules.TestName; +import org.junit.rules.Timeout; +import org.owasp.esapi.Authenticator; +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.EncoderConstants; +import org.owasp.esapi.HTTPUtilities; +import org.owasp.esapi.Logger; +import org.owasp.esapi.User; +import org.owasp.esapi.errors.AuthenticationException; +import org.owasp.esapi.errors.EncryptionException; +import org.owasp.esapi.http.MockHttpServletRequest; +import org.owasp.esapi.http.MockHttpServletResponse; + +/** + * The Class AuthenticatorTest. + * + * @author Jeff Williams (jeff.williams@aspectsecurity.com) + */ +public class AuthenticatorTest { + private static Authenticator instance; + /** + * User session information is stored on a per-thread basis. So long as this has potential to run single threaded then we'll maintain a synchronous nature execution. + * This is done to prevent tests corrupting each others states since all will be executed on a limited set of Threads within the JVM. + */ + private static Semaphore threadIsolation = new Semaphore(1, true); + + @Rule + public ErrorCollector collector = new ErrorCollector(); + @Rule + public Timeout testTimout = new Timeout(5, TimeUnit.MINUTES); + @Rule + public TestName name = new TestName(); + + @BeforeClass + public static void setUpStatic() { + instance = ESAPI.authenticator(); + } + + @Before + public void setup() throws InterruptedException { + while (!threadIsolation.tryAcquire(500, TimeUnit.MILLISECONDS)) { + //Spurious Interrupt Guard + } + } + + @After + public void cleanup() { + try { + instance.logout(); + instance.clearCurrent(); + HttpServletRequest request = ESAPI.httpUtilities().getCurrentRequest(); + HttpServletResponse response = ESAPI.httpUtilities().getCurrentResponse(); + if (request != null && response != null) { + //I don't know why killAllCookies doesn't nullcheck state. I'm assuming this is unique to the test environment. + ESAPI.httpUtilities().killAllCookies(); + } + ESAPI.httpUtilities().clearCurrent(); + } finally { + threadIsolation.release(); + } + } + + + /** + * Test of createAccount method, of class org.owasp.esapi.Authenticator. + * + * @throws AuthenticationException + * the authentication exception + * @throws EncryptionException + */ + @Test public void testCreateUser() throws AuthenticationException, EncryptionException { + System.out.println("createUser"); + String accountName = ESAPI.randomizer().getRandomString(8, EncoderConstants.CHAR_ALPHANUMERICS); + String password = instance.generateStrongPassword(); + User user = instance.createUser(accountName, password, password); + assertTrue(user.verifyPassword(password)); + try { + instance.createUser(accountName, password, password); // duplicate user + fail(); + } catch (AuthenticationException e) { + // success + } + try { + instance.createUser(ESAPI.randomizer().getRandomString(8, EncoderConstants.CHAR_ALPHANUMERICS), "password1", "password2"); // don't match + fail(); + } catch (AuthenticationException e) { + // success + } + try { + instance.createUser(ESAPI.randomizer().getRandomString(8, EncoderConstants.CHAR_ALPHANUMERICS), "weak1", "weak1"); // weak password + fail(); + } catch (AuthenticationException e) { + // success + } + try { + instance.createUser(null, "weak1", "weak1"); // null username + fail(); + } catch (AuthenticationException e) { + // success + } + try { + instance.createUser(ESAPI.randomizer().getRandomString(8, EncoderConstants.CHAR_ALPHANUMERICS), null, null); // null password + fail(); + } catch (AuthenticationException e) { + // success + } + try { + String uName = "ea234kEknr"; //sufficiently random password that also works as a username + instance.createUser(uName, uName, uName); // using username as password + fail(); + } catch (AuthenticationException e) { + // success + } + } + + /** + * Test of generateStrongPassword method, of class + * org.owasp.esapi.Authenticator. + * + * @throws AuthenticationException + * the authentication exception + */ + @Test public void testGenerateStrongPassword() throws AuthenticationException { + System.out.println("generateStrongPassword"); + String oldPassword = "iiiiiiiiii"; // i is not allowed in passwords - this prevents failures from containing pieces of old password + String newPassword = null; + String username = "FictionalEsapiUser"; + User user = new DefaultUser(username); + for (int i = 0; i < 100; i++) { + try { + newPassword = instance.generateStrongPassword(); + instance.verifyPasswordStrength(oldPassword, newPassword, user); + } catch( AuthenticationException e ) { + System.out.println( " FAILED >> " + newPassword + " : " + e.getLogMessage()); + fail(); + } + } + try { + instance.verifyPasswordStrength("test56^$test", "abcdx56^$sl", user ); + } catch( AuthenticationException e ) { + // expected + } + } + + + /** + * Test of getCurrentUser method, of class org.owasp.esapi.Authenticator. + * + * + * @throws Exception + */ + @Test public void testGetCurrentUser() throws Exception { + System.out.println("getCurrentUser"); + String username1 = ESAPI.randomizer().getRandomString(8, EncoderConstants.CHAR_ALPHANUMERICS); + String username2 = ESAPI.randomizer().getRandomString(8, EncoderConstants.CHAR_ALPHANUMERICS); + User user1 = instance.createUser(username1, "getCurrentUser", "getCurrentUser"); + User user2 = instance.createUser(username2, "getCurrentUser", "getCurrentUser"); + user1.enable(); + MockHttpServletRequest request = new MockHttpServletRequest(); + MockHttpServletResponse response = new MockHttpServletResponse(); + ESAPI.httpUtilities().setCurrentHTTP(request, response); + user1.loginWithPassword("getCurrentUser"); + User currentUser = instance.getCurrentUser(); + assertEquals( currentUser, user1 ); + instance.setCurrentUser( user2 ); + assertFalse( currentUser.getAccountName().equals( user2.getAccountName() ) ); + + Runnable echo = new Runnable() { + public void run() { + User a = null; + try { + String password = instance.generateStrongPassword(); + //Create account name using random strings to guarantee uniqueness among running threads. + String accountName=ESAPI.randomizer().getRandomString(8, EncoderConstants.CHAR_ALPHANUMERICS); + a = instance.getUser(accountName); + if ( a != null ) { + instance.removeUser(accountName); + } + a = instance.createUser(accountName, password, password); + instance.setCurrentUser(a); + } catch (AuthenticationException e) { + //Use ErrorCollector to fail test. + collector.addError(e); + } + User b = instance.getCurrentUser(); + collector.checkThat("Logged in user should equal original user", a.equals(b), new IsEqual(Boolean.TRUE)); + } + }; + ThreadGroup tg = new ThreadGroup("test"); + for ( int i = 0; i<10; i++ ) { + new Thread( tg, echo ).start(); + } + while (tg.activeCount() > 0 ) { + Thread.sleep(100); + } + } + + /** + * Test of getUser method, of class org.owasp.esapi.Authenticator. + * + * @throws AuthenticationException + * the authentication exception + */ + @Test public void testGetUser() throws AuthenticationException { + System.out.println("getUser"); + String password = instance.generateStrongPassword(); + String accountName=ESAPI.randomizer().getRandomString(8, EncoderConstants.CHAR_ALPHANUMERICS); + instance.createUser(accountName, password, password); + assertNotNull(instance.getUser( accountName )); + assertNull(instance.getUser( ESAPI.randomizer().getRandomString(8, EncoderConstants.CHAR_ALPHANUMERICS) )); + } + + /** + * + * @throws org.owasp.esapi.errors.AuthenticationException + */ + @Test public void testGetUserFromRememberToken() throws AuthenticationException { + System.out.println("getUserFromRememberToken"); + String password = instance.generateStrongPassword(); + String accountName=ESAPI.randomizer().getRandomString(8, EncoderConstants.CHAR_ALPHANUMERICS); + User user = instance.createUser(accountName, password, password); + user.enable(); + MockHttpServletRequest request = new MockHttpServletRequest(); + MockHttpServletResponse response = new MockHttpServletResponse(); + ESAPI.httpUtilities().setCurrentHTTP(request, response); + + System.out.println("getUserFromRememberToken - expecting failure"); + request.setCookie( HTTPUtilities.REMEMBER_TOKEN_COOKIE_NAME, "ridiculous" ); + try { + instance.login( request, response ); // wrong cookie will fail + fail(); + } catch( AuthenticationException e ) { + // expected + } + + System.out.println("getUserFromRememberToken - expecting success"); + request = new MockHttpServletRequest(); + ESAPI.httpUtilities().setCurrentHTTP(request, response); + ESAPI.authenticator().setCurrentUser(user); + String newToken = ESAPI.httpUtilities().setRememberToken(request, response, password, 10000, "test.com", request.getContextPath() ); + request.setCookie( HTTPUtilities.REMEMBER_TOKEN_COOKIE_NAME, newToken ); + user.logout(); // logout the current user so we can log them in with the remember cookie + User test2 = instance.login( request, response ); + assertSame( user, test2 ); + } + + + + /** + * Test get user from session. + * + * @throws AuthenticationException + * the authentication exception + */ + @Test public void testGetUserFromSession() throws AuthenticationException { + System.out.println("getUserFromSession"); + assumeTrue(instance instanceof FileBasedAuthenticator); + String accountName=ESAPI.randomizer().getRandomString(8, EncoderConstants.CHAR_ALPHANUMERICS); + String password = instance.generateStrongPassword(); + User user = instance.createUser(accountName, password, password); + user.enable(); + MockHttpServletRequest request = new MockHttpServletRequest(); + request.addParameter("username", accountName); + request.addParameter("password", password); + MockHttpServletResponse response = new MockHttpServletResponse(); + ESAPI.httpUtilities().setCurrentHTTP( request, response ); + instance.login( request, response); + User test = ((FileBasedAuthenticator)instance).getUserFromSession(); + assertEquals( user, test ); + } + + /** + * Test get user names. + * + * @throws AuthenticationException + * the authentication exception + */ + @Test public void testGetUserNames() throws AuthenticationException { + System.out.println("getUserNames"); + String password = instance.generateStrongPassword(); + String[] testnames = new String[10]; + for(int i=0;i allowedExecutables = secConf.getAllowedExecutables(); + + //is this really what should be returned? what about an empty list? + assertEquals(1, allowedExecutables.size()); + assertEquals("", allowedExecutables.get(0)); + + + Properties properties = new Properties(); + properties.setProperty(APPROVED_EXECUTABLES, String.valueOf("/bin/bzip2,/bin/diff, /bin/cvs")); + secConf = new DefaultSecurityConfiguration(properties); + allowedExecutables = secConf.getAllowedExecutables(); + assertEquals(3, allowedExecutables.size()); + assertEquals("/bin/bzip2", allowedExecutables.get(0)); + assertEquals("/bin/diff", allowedExecutables.get(1)); + + //this seems less than optimal, maybe each value should have a trim() done to it + //at least we know that this behavior exists, the property should'nt have spaces between values + assertEquals(" /bin/cvs", allowedExecutables.get(2)); + } + + @Test + public void testGetAllowedFileExtensions() { + + DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new Properties()); + java.util.List allowedFileExtensions = secConf.getAllowedFileExtensions(); + assertFalse(allowedFileExtensions.isEmpty()); + + + Properties properties = new Properties(); + properties.setProperty(APPROVED_UPLOAD_EXTENSIONS, String.valueOf(".txt,.xml,.html,.png")); + secConf = new DefaultSecurityConfiguration(properties); + allowedFileExtensions = secConf.getAllowedFileExtensions(); + assertEquals(4, allowedFileExtensions.size()); + assertEquals(".html", allowedFileExtensions.get(2)); + } + + @Test + public void testGetAllowedFileUploadSize() { + DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new Properties()); + //assert that the default is of some reasonable size + assertTrue(secConf.getAllowedFileUploadSize() > (1024 * 100)); + + final int expected = (1024 * 1000); + secConf = this.createWithProperty(MAX_UPLOAD_FILE_BYTES, String.valueOf(expected)); + assertEquals(expected, secConf.getAllowedFileUploadSize()); + } + + @Test + public void testGetParameterNames() { + //test the default + DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new Properties()); + assertEquals("password", secConf.getPasswordParameterName()); + assertEquals("username", secConf.getUsernameParameterName()); + + Properties properties = new Properties(); + properties.setProperty(PASSWORD_PARAMETER_NAME, "j_password"); + properties.setProperty(USERNAME_PARAMETER_NAME, "j_username"); + secConf = new DefaultSecurityConfiguration(properties); + assertEquals("j_password", secConf.getPasswordParameterName()); + assertEquals("j_username", secConf.getUsernameParameterName()); + } + + @Test + public void testGetEncryptionAlgorithm() { + //test the default + DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new Properties()); + assertEquals("AES", secConf.getEncryptionAlgorithm()); + + secConf = this.createWithProperty(ENCRYPTION_ALGORITHM, "3DES"); + assertEquals("3DES", secConf.getEncryptionAlgorithm()); + } + + @Test + public void testGetCipherXProperties() { + DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new Properties()); + assertEquals("AES/CBC/PKCS5Padding", secConf.getCipherTransformation()); + //assertEquals("AES/CBC/PKCS5Padding", secConf.getC); + + Properties properties = new Properties(); + properties.setProperty(CIPHER_TRANSFORMATION_IMPLEMENTATION, "Blowfish/CFB/ISO10126Padding"); + secConf = new DefaultSecurityConfiguration(properties); + assertEquals("Blowfish/CFB/ISO10126Padding", secConf.getCipherTransformation()); + + secConf.setCipherTransformation("DESede/PCBC/PKCS5Padding"); + assertEquals("DESede/PCBC/PKCS5Padding", secConf.getCipherTransformation()); + + secConf.setCipherTransformation(null);//sets it back to default + assertEquals("Blowfish/CFB/ISO10126Padding", secConf.getCipherTransformation()); + } + + // NOTE: When SecurityConfiguration.getIVType() is finally removed, this test can be as well. + @Test + public void testIV() { + DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new Properties()); + assertEquals("random", secConf.getIVType()); // Ensure that 'random' is the default type for getIVType(). + + Properties props = new Properties(); + String ivType = null; + props.setProperty(IV_TYPE, "fixed"); // No longer supported. + + secConf = new DefaultSecurityConfiguration( props ); + try { + ivType = secConf.getIVType(); // This should now throw a Configuration Exception. + fail("Expected ConfigurationException to be thrown for " + IV_TYPE + "=" + ivType); + } + catch (ConfigurationException ce) { + assertNotNull(ce.getMessage()); + } + + props.setProperty(IV_TYPE, "illegal"); // This will just result in a logSpecial message & "random" is returned. + secConf = new DefaultSecurityConfiguration(props); + ivType = secConf.getIVType(); + assertEquals(ivType, "random"); + } + + @Test + public void testGetAllowMultipleEncoding() { + DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new Properties()); + assertFalse(secConf.getAllowMultipleEncoding()); + + secConf = this.createWithProperty(ALLOW_MULTIPLE_ENCODING, "yes"); + assertTrue(secConf.getAllowMultipleEncoding()); + + secConf = this.createWithProperty(ALLOW_MULTIPLE_ENCODING, "true"); + assertTrue(secConf.getAllowMultipleEncoding()); + + secConf = this.createWithProperty(ALLOW_MULTIPLE_ENCODING, "no"); + assertFalse(secConf.getAllowMultipleEncoding()); + } + + @Test + public void testGetDefaultCanonicalizationCodecs() { + DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new Properties()); + assertFalse(secConf.getDefaultCanonicalizationCodecs().isEmpty()); + + String property = "org.owasp.esapi.codecs.TestCodec1,org.owasp.esapi.codecs.TestCodec2"; + secConf = this.createWithProperty(CANONICALIZATION_CODECS, property); + assertTrue(secConf.getDefaultCanonicalizationCodecs().contains("org.owasp.esapi.codecs.TestCodec1")); + } + + @Test + public void testGetDisableIntrusionDetection() { + DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new Properties()); + assertFalse(secConf.getDisableIntrusionDetection()); + + secConf = this.createWithProperty(DISABLE_INTRUSION_DETECTION, "TRUE"); + assertTrue(secConf.getDisableIntrusionDetection()); + + secConf = this.createWithProperty(DISABLE_INTRUSION_DETECTION, "true"); + assertTrue(secConf.getDisableIntrusionDetection()); + + secConf = this.createWithProperty(DISABLE_INTRUSION_DETECTION, "false"); + assertFalse(secConf.getDisableIntrusionDetection()); + } + + @Test + public void testNoSuchPropFile(){ + try { + // Do NOT create a file by this name!!! -----vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration("NoSuchEsapiPropFileXyzzy.properties"); + } + catch( ConfigurationException cex ) { + assertNotNull("Caught exception with null exception msg", cex.getMessage() ); + assertFalse("Exception msg is empty string", cex.getMessage().equals("") ); + } + catch( Throwable t ) { + fail("testNoSuchPropFile(): Unexpected exception type: " + t.getClass().getName() + "; ex msg: " + t); + } + + } + + private String patternOrNull(Pattern p){ + return null==p?null:p.pattern(); + } + + @Test + public void testRootCPLoading(){ + DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration("ESAPI-root-cp.properties"); + assertEquals(patternOrNull(secConf.getValidationPattern("Test1")), "ValueFromFile1"); + assertNull(secConf.getValidationPattern("Test2")); + assertNull(secConf.getValidationPattern("TestC")); + } + + @Test + public void testRootCPLoadingAlt(){ + // This should work also via the class loader. + DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration("esapi/ESAPI-SingleValidatorFileChecker.properties"); + assertEquals(patternOrNull(secConf.getValidationPattern("Test1")), "ValueFromFile1"); + assertNull(secConf.getValidationPattern("Test2")); + assertNull(secConf.getValidationPattern("TestC")); + } + + @Test + public void testRootCPLoadingAlt2(){ + try { + // This should fail, because of the '/' on the resourse. + DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration("/ESAPI-root-cp.properties"); + } + catch( ConfigurationException cex ) { + assertNotNull("Caught exception with null exception msg", cex.getMessage() ); + assertFalse("Exception msg is empty string", cex.getMessage().equals("") ); + } + catch( Throwable t ) { + fail("testNoSuchPropFile(): Unexpected exception type: " + t.getClass().getName() + "; ex msg: " + t); + } + } + + @Test + public void testValidationsPropertiesFileOptions(){ + DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration("ESAPI-SingleValidatorFileChecker.properties"); + assertEquals(patternOrNull(secConf.getValidationPattern("Test1")), "ValueFromFile1"); + assertNull(secConf.getValidationPattern("Test2")); + assertNull(secConf.getValidationPattern("TestC")); + + secConf = new DefaultSecurityConfiguration("ESAPI-DualValidatorFileChecker.properties"); + assertEquals(patternOrNull(secConf.getValidationPattern("Test1")), "ValueFromFile1"); + assertEquals(patternOrNull(secConf.getValidationPattern("Test2")), "ValueFromFile2"); + assertNull(secConf.getValidationPattern("TestC")); + + secConf = new DefaultSecurityConfiguration("ESAPI-CommaValidatorFileChecker.properties"); + assertEquals(patternOrNull(secConf.getValidationPattern("TestC")), "ValueFromCommaFile"); + assertNull(secConf.getValidationPattern("Test1")); + assertNull(secConf.getValidationPattern("Test2")); + + secConf = new DefaultSecurityConfiguration("ESAPI-QuotedValidatorFileChecker.properties"); + assertEquals(patternOrNull(secConf.getValidationPattern("Test1")), "ValueFromFile1"); + assertEquals(patternOrNull(secConf.getValidationPattern("Test2")), "ValueFromFile2"); + assertEquals(patternOrNull(secConf.getValidationPattern("TestC")), "ValueFromCommaFile"); + } + + @Test + public void DefaultSearchPathTest(){ + assertEquals("", DefaultSearchPath.ROOT.value()); + assertEquals("resourceDirectory/", DefaultSearchPath.RESOURCE_DIRECTORY.value()); + assertEquals(".esapi/", DefaultSearchPath.DOT_ESAPI.value()); + assertEquals("esapi/", DefaultSearchPath.ESAPI.value()); + assertEquals("resources/", DefaultSearchPath.RESOURCES.value()); + assertEquals("src/main/resources/", DefaultSearchPath.SRC_MAIN_RESOURCES.value()); + } + + @Test + public void DefaultSearchPathEnumChanges(){ + int expected = 6; + int testValue = DefaultSearchPath.values().length; + assertEquals(expected, testValue); + } + + @Test + public void defaultPropertiesTest(){ + SecurityConfiguration sc = ESAPI.securityConfiguration(); +// # Maximum size of JSESSIONID for the application--the validator regex may have additional values. +// HttpUtilities.HTTPJSESSIONIDLENGTH=50 + assertEquals(50, sc.getIntProp("HttpUtilities.HTTPJSESSIONIDLENGTH")); +// # Maximum length of a URL (see https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers) +// HttpUtilities.URILENGTH=2000 + assertEquals(2000, sc.getIntProp("HttpUtilities.URILENGTH")); +// # Maximum length for an http scheme +// HttpUtilities.HTTPSCHEMELENGTH=10 + assertEquals(10, sc.getIntProp("HttpUtilities.HTTPSCHEMELENGTH")); +// # Maximum length for an http host +// HttpUtilities.HTTPHOSTLENGTH=100 + assertEquals(100, sc.getIntProp("HttpUtilities.HTTPHOSTLENGTH")); +// # Maximum length for an http path +// HttpUtilities.HTTPPATHLENGTH=150 + assertEquals(150, sc.getIntProp("HttpUtilities.HTTPPATHLENGTH")); +// #Maximum length for a context path +// HttpUtilities.contextPathLength=150 + assertEquals(150, sc.getIntProp("HttpUtilities.contextPathLength")); +// #Maximum length for an httpServletPath +// HttpUtilities.HTTPSERVLETPATHLENGTH=100 + assertEquals(100, sc.getIntProp("HttpUtilities.HTTPSERVLETPATHLENGTH")); +// #Maximum length for an http query parameter name +// HttpUtilities.httpQueryParamNameLength=100 + assertEquals(100, sc.getIntProp("HttpUtilities.httpQueryParamNameLength")); +// #Maximum length for an http query parameter -- old default was 2000, but that's the max length for a URL... +// HttpUtilities.httpQueryParamValueLength=500 + assertEquals(500, sc.getIntProp("HttpUtilities.httpQueryParamValueLength")); +// # Maximum size of HTTP header key--the validator regex may have additional values. +// HttpUtilities.MaxHeaderNameSize=256 + assertEquals(256, sc.getIntProp("HttpUtilities.MaxHeaderNameSize")); +// # Maximum size of HTTP header value--the validator regex may have additional values. +// HttpUtilities.MaxHeaderValueSize=4096 + assertEquals(4096, sc.getIntProp("HttpUtilities.MaxHeaderValueSize")); +// # Maximum length of a redirect +// HttpUtilities.maxRedirectLength=512 + assertEquals(512, sc.getIntProp("HttpUtilities.maxRedirectLength")); + } + + // Test some of the deprecated methods to make sure I didn't screw them up + // given the double negatives on some these properties. + @Test + public void testDeprecatedMethods() + { + assertTrue("1: Deprecated (1st) method returns different value than new (2nd) method", + ESAPI.securityConfiguration().getDisableIntrusionDetection() == + ESAPI.securityConfiguration().getBooleanProp( DISABLE_INTRUSION_DETECTION ) + ); + // TODO: add some more tests here for the deprecated replacements. + } +} diff --git a/src/test/java/org/owasp/esapi/reference/DefaultValidaterDateAPITest.java b/src/test/java/org/owasp/esapi/reference/DefaultValidaterDateAPITest.java new file mode 100644 index 000000000..3322633f6 --- /dev/null +++ b/src/test/java/org/owasp/esapi/reference/DefaultValidaterDateAPITest.java @@ -0,0 +1,198 @@ +package org.owasp.esapi.reference; + + +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isA; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.powermock.api.mockito.PowerMockito.whenNew; + +import java.text.DateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.Locale; + +import org.hamcrest.core.Is; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.TestName; +import org.junit.runner.RunWith; +import org.owasp.esapi.Encoder; +import org.owasp.esapi.ValidationErrorList; +import org.owasp.esapi.errors.IntrusionException; +import org.owasp.esapi.errors.ValidationException; +import org.owasp.esapi.reference.validation.DateValidationRule; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +/** + * This class contains a subsection of tests of the DefaultValidator class + * SPECIFIC TO THE DATE VALIDATION API. + * + */ +@RunWith(PowerMockRunner.class) +@PrepareForTest(DefaultValidator.class) +public class DefaultValidaterDateAPITest { + @Rule + public ExpectedException exEx = ExpectedException.none(); + @Rule + public TestName testName = new TestName(); + private String dateString="Input Does not matter in this context"; + + private ValidationException validationEx; + private Date testDate = new Date(); + private String contextStr; + private Encoder mockEncoder; + private DateFormat testFormat = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.US); + private DateValidationRule spyDateRule; + private ValidationErrorList errors = new ValidationErrorList(); + + private DefaultValidator uit; + + + @Before + public void setup() throws Exception { + contextStr = testName.getMethodName(); + + validationEx = new ValidationException(contextStr, contextStr); + + mockEncoder = mock(Encoder.class); + uit = new DefaultValidator(mockEncoder); + + spyDateRule = new DateValidationRule(contextStr, mockEncoder, testFormat); + spyDateRule = spy(spyDateRule); + whenNew(DateValidationRule.class).withArguments(anyString(), eq(mockEncoder), eq(testFormat)).thenReturn(spyDateRule); + + errors = spy(errors); + whenNew(ValidationErrorList.class).withNoArguments().thenReturn(errors); + } + + @After + public void tearDown() { + verifyNoMoreInteractions(spyDateRule, errors); + } + + @Test + public void testIsValidDate() { + doReturn(testDate).when(spyDateRule).sanitize(eq(contextStr), eq(dateString), isA(ValidationErrorList.class)); + + boolean isValid = uit.isValidDate(contextStr, dateString, testFormat, true); + Assert.assertTrue("Mock is configured to return a valid date, return should be equally valid.", isValid); + + verify(errors, atLeastOnce()).isEmpty(); + verify(errors, times(0)).errors(); + verify(spyDateRule, times(1)).setAllowNull(true); + verify(spyDateRule, times(1)).sanitize(eq(contextStr), eq(dateString), isA(ValidationErrorList.class)); + } + + @Test + public void testIsValidDateErrorList() { + doReturn(testDate).when(spyDateRule).sanitize(eq(contextStr), eq(dateString), isA(ValidationErrorList.class)); + + boolean isValid = uit.isValidDate(contextStr, dateString, testFormat, true, errors); + Assert.assertTrue("Mock is configured to return a valid date, return should be equally valid.", isValid); + + verify(errors, atLeastOnce()).isEmpty(); + verify(errors, times(0)).errors(); + verify(spyDateRule, times(1)).setAllowNull(true); + verify(spyDateRule, times(1)).sanitize(eq(contextStr), eq(dateString), eq(errors)); + } + + @Test + public void testGetValidDate() throws IntrusionException, ValidationException { + doReturn(testDate).when(spyDateRule).sanitize(eq(contextStr), eq(dateString), isA(ValidationErrorList.class)); + Date validDate = uit.getValidDate(contextStr, dateString, testFormat, true); + Assert.assertEquals("ValidDate should match the mock's configured return value", testDate, validDate); + + verify(errors, atLeastOnce()).isEmpty(); + verify(errors, times(0)).errors(); + verify(spyDateRule, times(1)).setAllowNull(true); + verify(spyDateRule, times(1)).sanitize(eq(contextStr), eq(dateString), isA(ValidationErrorList.class)); + } + + @Test + public void testGetValidDateErrorList() { + doReturn(testDate).when(spyDateRule).sanitize(eq(contextStr), eq(dateString), isA(ValidationErrorList.class)); + Date validDate = uit.getValidDate(contextStr, dateString, testFormat, true, errors); + Assert.assertEquals("ValidDate should match the mock's configured return value", testDate, validDate); + + verify(errors, atLeastOnce()).isEmpty(); + verify(errors, times(0)).errors(); + verify(spyDateRule, times(1)).setAllowNull(true); + verify(spyDateRule, times(1)).sanitize(eq(contextStr), eq(dateString), eq(errors)); + } + + + @Test + public void testIsValidDateOnValidationError() { + doReturn(false).when(errors).isEmpty(); + doReturn(Arrays.asList(validationEx)).when(errors).errors(); + + doReturn(testDate).when(spyDateRule).sanitize(eq(contextStr), eq(dateString), isA(ValidationErrorList.class)); + + boolean isValid = uit.isValidDate(contextStr, dateString, testFormat, true); + Assert.assertFalse("On ValidationException input should be invalid", isValid); + + verify(errors, atLeastOnce()).isEmpty(); + verify(errors, times(1)).errors(); + verify(spyDateRule, times(1)).setAllowNull(true); + verify(spyDateRule, times(1)).sanitize(eq(contextStr), eq(dateString), isA(ValidationErrorList.class)); + } + + @Test + public void testIsValidDateErrorListOnValidationError() { + doReturn(false).when(errors).isEmpty(); + doReturn(Arrays.asList(validationEx)).when(errors).errors(); + + doReturn(testDate).when(spyDateRule).sanitize(eq(contextStr), eq(dateString), isA(ValidationErrorList.class)); + + boolean isValid = uit.isValidDate(contextStr, dateString, testFormat, true, errors); + Assert.assertFalse("On ValidationException input should be invalid", isValid); + + verify(errors, times(2)).isEmpty(); + verify(errors, times(0)).errors(); + verify(spyDateRule, times(1)).setAllowNull(true); + verify(spyDateRule, times(1)).sanitize(eq(contextStr), eq(dateString), eq(errors)); + } + @Test + public void testGetValidDateOnValidationError() throws IntrusionException, ValidationException { + exEx.expect(Is.is(validationEx)); + doReturn(false).when(errors).isEmpty(); + doReturn(Arrays.asList(validationEx)).when(errors).errors(); + + doReturn(testDate).when(spyDateRule).sanitize(eq(contextStr), eq(dateString), isA(ValidationErrorList.class)); + try { + uit.getValidDate(contextStr, dateString, testFormat, true); + } finally { + verify(errors, atLeastOnce()).isEmpty(); + verify(errors, times(1)).errors(); + verify(spyDateRule, times(1)).setAllowNull(true); + verify(spyDateRule, times(1)).sanitize(eq(contextStr), eq(dateString), isA(ValidationErrorList.class)); + } + } + + @Test + public void testGetValidDateErrorListOnValidationError() { + doReturn(false).when(errors).isEmpty(); + doReturn(Arrays.asList(validationEx)).when(errors).errors(); + + doReturn(testDate).when(spyDateRule).sanitize(eq(contextStr), eq(dateString), isA(ValidationErrorList.class)); + Date validDate = uit.getValidDate(contextStr, dateString, testFormat, true, errors); + Assert.assertNull(validDate); + verify(errors, atLeastOnce()).isEmpty(); + verify(errors, times(0)).errors(); + verify(spyDateRule, times(1)).setAllowNull(true); + verify(spyDateRule, times(1)).sanitize(eq(contextStr), eq(dateString), isA(ValidationErrorList.class)); + } + +} diff --git a/src/test/java/org/owasp/esapi/reference/DefaultValidatorInputStringAPITest.java b/src/test/java/org/owasp/esapi/reference/DefaultValidatorInputStringAPITest.java new file mode 100644 index 000000000..d62907c07 --- /dev/null +++ b/src/test/java/org/owasp/esapi/reference/DefaultValidatorInputStringAPITest.java @@ -0,0 +1,231 @@ +package org.owasp.esapi.reference; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.powermock.api.mockito.PowerMockito.whenNew; + +import java.util.regex.Pattern; + +import org.hamcrest.core.Is; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.TestName; +import org.junit.runner.RunWith; +import org.mockito.ArgumentMatchers; +import org.mockito.Mock; +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Encoder; +import org.owasp.esapi.SecurityConfiguration; +import org.owasp.esapi.ValidationErrorList; +import org.owasp.esapi.errors.ValidationException; +import org.owasp.esapi.reference.validation.StringValidationRule; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +/** + * This class contains a subsection of tests of the DefaultValidator class + * SPECIFIC TO THE INPUT 'STRING' VALIDATION API. + * + */ +@RunWith(PowerMockRunner.class) +@PrepareForTest({DefaultValidator.class, ESAPI.class}) +public class DefaultValidatorInputStringAPITest { + private static final String ESAPY_SECURITY_CONFIGURATION_GETTER_METHOD_NAME = "securityConfiguration"; + private static final Pattern TEST_PATTERN = Pattern.compile(""); + @Rule + public ExpectedException exEx = ExpectedException.none(); + @Rule + public TestName testName = new TestName(); + @Mock + private SecurityConfiguration mockSecConfig; + @Mock + private Encoder mockEncoder; + + private ValidationException validationEx; + private String contextStr; + private StringValidationRule spyStringRule; + private ValidationErrorList errors = new ValidationErrorList(); + + private DefaultValidator uit; + private String testValidatorType; + private String validatorResultString; + private int testMaximumLength; + + @Before + public void setup() throws Exception { + contextStr = testName.getMethodName(); + testValidatorType = testName.getMethodName() + "_validator_type"; + validatorResultString = testName.getMethodName() + "_validator_result"; + testMaximumLength = testName.getMethodName().length(); + + validationEx = new ValidationException(contextStr, contextStr); + + mockEncoder = mock(Encoder.class); + uit = new DefaultValidator(mockEncoder); + + //Don't care how the StringValidationRule works, we just care that we forwarded the information as expected. + spyStringRule = new StringValidationRule(testValidatorType, mockEncoder); + spyStringRule = spy(spyStringRule); + doNothing().when(spyStringRule).addWhitelistPattern(ArgumentMatchers.any()); + doNothing().when(spyStringRule).setAllowNull(ArgumentMatchers.anyBoolean()); + doNothing().when(spyStringRule).setMaximumLength(ArgumentMatchers.anyInt()); + doReturn(validatorResultString).when(spyStringRule).getValid(ArgumentMatchers.anyString(), ArgumentMatchers.anyString()); + whenNew(StringValidationRule.class).withArguments(eq(testValidatorType), eq(mockEncoder)).thenReturn(spyStringRule); + + errors = spy(errors); + whenNew(ValidationErrorList.class).withNoArguments().thenReturn(errors); + + + PowerMockito.mockStatic(ESAPI.class); + PowerMockito.when(ESAPI.class, ESAPY_SECURITY_CONFIGURATION_GETTER_METHOD_NAME).thenReturn(mockSecConfig); + + + when(mockSecConfig.getValidationPattern(testValidatorType)).thenReturn(TEST_PATTERN); + + } + + @After + public void verifyDelegateCalls() { + verify(mockSecConfig, times(1)).getValidationPattern(testValidatorType); + + PowerMockito.verifyNoMoreInteractions(spyStringRule, mockSecConfig, mockEncoder); + } + + @Test + public void getValidInputNullAllowedPassthrough() throws Exception { + String safeValue = uit.getValidInput(contextStr, testName.getMethodName(), testValidatorType, testMaximumLength, true); + assertEquals(validatorResultString, safeValue); + verify(spyStringRule, times(1)).addWhitelistPattern(TEST_PATTERN); + verify(spyStringRule, times(1)).setAllowNull(true); + verify(spyStringRule, times(0)).setAllowNull(false); + verify(spyStringRule, times(1)).setMaximumLength(testMaximumLength); + verify(spyStringRule, times(1)).setCanonicalize(true); + verify(spyStringRule, times(1)).getValid(contextStr, testName.getMethodName()); + } + + @Test + public void getValidInputNullNotAllowedPassthrough() throws Exception { + String safeValue = uit.getValidInput(contextStr, testName.getMethodName(), testValidatorType, testMaximumLength, false); + assertEquals(validatorResultString, safeValue); + verify(spyStringRule, times(1)).addWhitelistPattern(TEST_PATTERN); + verify(spyStringRule, times(0)).setAllowNull(true); + verify(spyStringRule, times(1)).setAllowNull(false); + verify(spyStringRule, times(1)).setMaximumLength(testMaximumLength); + verify(spyStringRule, times(1)).setCanonicalize(true); + verify(spyStringRule, times(1)).getValid(contextStr, testName.getMethodName()); + } + + @Test + public void getValidInputNullPatternThrows() throws Exception { + exEx.expect(IllegalArgumentException.class); + exEx.expectMessage(testValidatorType + "] was not set via the ESAPI validation configuration"); + when(mockSecConfig.getValidationPattern(testValidatorType)).thenReturn(null); + + uit.getValidInput(contextStr, testName.getMethodName(), testValidatorType, testMaximumLength, true); + } + + @Test + public void getValidInputValidationExceptionPropagates() throws Exception { + exEx.expect(Is.is(validationEx)); + + doThrow(validationEx).when(spyStringRule).getValid(ArgumentMatchers.anyString(), ArgumentMatchers.anyString()); + try { + uit.getValidInput(contextStr, testName.getMethodName(), testValidatorType, testMaximumLength, true); + } finally { + verify(spyStringRule, times(1)).addWhitelistPattern(TEST_PATTERN); + verify(spyStringRule, times(1)).setAllowNull(true); + verify(spyStringRule, times(0)).setAllowNull(false); + verify(spyStringRule, times(1)).setMaximumLength(testMaximumLength); + verify(spyStringRule, times(1)).setCanonicalize(true); + verify(spyStringRule, times(1)).getValid(contextStr, testName.getMethodName()); + } + } + + @Test + public void getValidInputValidationExceptionErrorList() throws Exception { + ValidationErrorList errorList = new ValidationErrorList(); + + doThrow(validationEx).when(spyStringRule).getValid(ArgumentMatchers.anyString(), ArgumentMatchers.anyString()); + String result = uit.getValidInput(contextStr, testName.getMethodName(), testValidatorType, testMaximumLength, true,errorList); + assertTrue(result.isEmpty()); + assertEquals(1, errorList.size()); + assertEquals(validationEx, errorList.getError(contextStr)); + verify(spyStringRule, times(1)).addWhitelistPattern(TEST_PATTERN); + verify(spyStringRule, times(1)).setAllowNull(true); + verify(spyStringRule, times(0)).setAllowNull(false); + verify(spyStringRule, times(1)).setMaximumLength(testMaximumLength); + verify(spyStringRule, times(1)).setCanonicalize(true); + verify(spyStringRule, times(1)).getValid(contextStr, testName.getMethodName()); + } + + + @Test + public void isValidInputNullAllowedPassthrough() throws Exception { + boolean isValid= uit.isValidInput(contextStr, testName.getMethodName(), testValidatorType, testMaximumLength, true); + assertTrue(isValid); + + verify(spyStringRule, times(1)).addWhitelistPattern(TEST_PATTERN); + verify(spyStringRule, times(1)).setAllowNull(true); + verify(spyStringRule, times(0)).setAllowNull(false); + verify(spyStringRule, times(1)).setMaximumLength(testMaximumLength); + verify(spyStringRule, times(1)).setCanonicalize(true); + verify(spyStringRule, times(1)).getValid(contextStr, testName.getMethodName()); + } + + @Test + public void isValidInputValidationExceptionReturnsFalse() throws Exception { + doThrow(validationEx).when(spyStringRule).getValid(ArgumentMatchers.anyString(), ArgumentMatchers.anyString()); + boolean result = uit.isValidInput(contextStr, testName.getMethodName(), testValidatorType, testMaximumLength, true); + assertFalse(result); + verify(spyStringRule, times(1)).addWhitelistPattern(TEST_PATTERN); + verify(spyStringRule, times(1)).setAllowNull(true); + verify(spyStringRule, times(0)).setAllowNull(false); + verify(spyStringRule, times(1)).setMaximumLength(testMaximumLength); + verify(spyStringRule, times(1)).setCanonicalize(true); + verify(spyStringRule, times(1)).getValid(contextStr, testName.getMethodName()); + } + + @Test + public void isValidInputValidationExceptionErrorListReturnsFalse() throws Exception { + ValidationErrorList errorList = new ValidationErrorList(); + + doThrow(validationEx).when(spyStringRule).getValid(ArgumentMatchers.anyString(), ArgumentMatchers.anyString()); + boolean result = uit.isValidInput(contextStr, testName.getMethodName(), testValidatorType, testMaximumLength, true,errorList); + assertFalse(result); + assertEquals(1, errorList.size()); + assertEquals(validationEx, errorList.getError(contextStr)); + verify(errors, times(1)).addError(contextStr, validationEx); + verify(spyStringRule, times(1)).addWhitelistPattern(TEST_PATTERN); + verify(spyStringRule, times(1)).setAllowNull(true); + verify(spyStringRule, times(0)).setAllowNull(false); + verify(spyStringRule, times(1)).setMaximumLength(testMaximumLength); + verify(spyStringRule, times(1)).setCanonicalize(true); + verify(spyStringRule, times(1)).getValid(contextStr, testName.getMethodName()); + } + + @Test + public void canonicalizeSettingPassedThrough() throws Exception { + String safeValue = uit.getValidInput(contextStr, testName.getMethodName(), testValidatorType, testMaximumLength, false,false); + assertEquals(validatorResultString, safeValue); + verify(spyStringRule, times(1)).addWhitelistPattern(TEST_PATTERN); + verify(spyStringRule, times(0)).setAllowNull(true); + verify(spyStringRule, times(1)).setAllowNull(false); + verify(spyStringRule, times(1)).setMaximumLength(testMaximumLength); + verify(spyStringRule, times(1)).setCanonicalize(false); + verify(spyStringRule, times(1)).getValid(contextStr, testName.getMethodName()); + } +} diff --git a/src/test/java/org/owasp/esapi/reference/EncoderTest.java b/src/test/java/org/owasp/esapi/reference/EncoderTest.java new file mode 100644 index 000000000..51f72d063 --- /dev/null +++ b/src/test/java/org/owasp/esapi/reference/EncoderTest.java @@ -0,0 +1,1532 @@ +/** + * 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.reference; + +import static org.junit.Assert.assertNotEquals; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.junit.Ignore; +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Encoder; +import org.owasp.esapi.EncoderConstants; +import org.owasp.esapi.SecurityConfiguration; +import org.owasp.esapi.SecurityConfigurationWrapper; +import org.owasp.esapi.codecs.Codec; +import org.owasp.esapi.codecs.HTMLEntityCodec; +import org.owasp.esapi.codecs.MySQLCodec; +import org.owasp.esapi.codecs.OracleCodec; +import org.owasp.esapi.codecs.JSONCodec; +import org.owasp.esapi.codecs.PushbackString; +import org.owasp.esapi.codecs.UnixCodec; +import org.owasp.esapi.codecs.WindowsCodec; +import org.owasp.esapi.errors.EncodingException; +import org.owasp.esapi.errors.IntrusionException; +import org.owasp.esapi.Randomizer; + + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * The Class EncoderTest. + * + * @author Jeff Williams (jeff.williams@aspectsecurity.com) + */ +public class EncoderTest extends TestCase { + + private static class Conf extends SecurityConfigurationWrapper + { + private final List codecList; + + /** + * @param orig The original {@code SecurityConfiguration} to use as a basis. + * Generally, that will just be: {@code ESAPI.securityConfiguration()} + * @param codecsList List of {@code Codec}s to replace {@code Encoder.DefaultCodecList} + */ + Conf(SecurityConfiguration orig, List codecList) + { + super(orig); + this.codecList = codecList; + } + + @Override + public List getDefaultCanonicalizationCodecs() + { + return codecList; + } + } + private static final String PREFERRED_ENCODING = "UTF-8"; + + /** + * Instantiates a new encoder test. + * + * @param testName + * the test name + */ + public EncoderTest(String testName) { + super(testName); + } + + /** + * {@inheritDoc} + * @throws Exception + */ + protected void setUp() throws Exception { + // none + } + + /** + * {@inheritDoc}s + * @throws Exception + */ + protected void tearDown() throws Exception { + ESAPI.override(null); // Restore + } + + /** + * Suite. + * + * @return the test + */ + public static Test suite() { + TestSuite suite = new TestSuite(EncoderTest.class); + return suite; + } + + /** + * Test of canonicalize method, of class org.owasp.esapi.Encoder. + * + * @throws EncodingException + */ + public void testCanonicalize() throws EncodingException { + System.out.println("canonicalize"); + + ArrayList list = new ArrayList(); + list.add( "HTMLEntityCodec" ); + list.add( "PercentCodec" ); + Encoder instance = new DefaultEncoder( list ); + + // Test null paths + assertEquals( null, instance.canonicalize(null)); + assertEquals( null, instance.canonicalize(null, true)); + assertEquals( null, instance.canonicalize(null, false)); + assertEquals( null, instance.canonicalize(null, true, true)); + assertEquals( null, instance.canonicalize(null, true, false)); + assertEquals( null, instance.canonicalize(null, false, true)); + assertEquals( null, instance.canonicalize(null, false, false)); + + // test exception paths + assertEquals( "%", instance.canonicalize("%25", true)); + assertEquals( "%", instance.canonicalize("%25", false)); + + assertEquals( "%", instance.canonicalize("%25")); + assertEquals( "%F", instance.canonicalize("%25F")); + assertEquals( "<", instance.canonicalize("%3c")); + assertEquals( "<", instance.canonicalize("%3C")); + assertEquals( "%X1", instance.canonicalize("%X1")); + + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + + assertEquals( "%", instance.canonicalize("%")); + assertEquals( "%", instance.canonicalize("%")); + assertEquals( "%b", instance.canonicalize("%b")); + + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + + // percent encoding + assertEquals( "<", instance.canonicalize("%3c")); + assertEquals( "<", instance.canonicalize("%3C")); + + // html entity encoding + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("&lT")); + assertEquals( "<", instance.canonicalize("&Lt")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "<", instance.canonicalize("&lT;")); + assertEquals( "<", instance.canonicalize("≪")); + assertEquals( "<", instance.canonicalize("<")); + assertEquals( "&", instance.canonicalize("&")); + assertEquals( "〈", instance.canonicalize("&lang")); + + assertEquals( "", instance.canonicalize("%3Cscript%3Ealert%28%22hello%22%29%3B%3C%2Fscript%3E") ); + assertEquals( "", instance.canonicalize("%3Cscript>alert%28%22hello"%29%3B%3C%2Fscript%3E", false) ); + + // javascript escape syntax + ArrayList js = new ArrayList(); + js.add( "JavaScriptCodec" ); + instance = new DefaultEncoder( js ); + System.out.println( "JavaScript Decoding" ); + + assertEquals( "\0", instance.canonicalize("\\0")); + assertEquals( "\b", instance.canonicalize("\\b")); + assertEquals( "\t", instance.canonicalize("\\t")); + assertEquals( "\n", instance.canonicalize("\\n")); + assertEquals( ""+(char)0x0b, instance.canonicalize("\\v")); + assertEquals( "\f", instance.canonicalize("\\f")); + assertEquals( "\r", instance.canonicalize("\\r")); + assertEquals( "\'", instance.canonicalize("\\'")); + assertEquals( "\"", instance.canonicalize("\\\"")); + assertEquals( "\\", instance.canonicalize("\\\\")); + assertEquals( "\\<", instance.canonicalize("\\<")); + + assertEquals( "<", instance.canonicalize("\\u003c")); + assertEquals( "<", instance.canonicalize("\\U003c")); + assertEquals( "<", instance.canonicalize("\\u003C")); + assertEquals( "<", instance.canonicalize("\\U003C")); + assertEquals( "<", instance.canonicalize("\\x3c")); + assertEquals( "<", instance.canonicalize("\\X3c")); + assertEquals( "<", instance.canonicalize("\\x3C")); + assertEquals( "<", instance.canonicalize("\\X3C")); + + // css escape syntax + // be careful because some codecs see \0 as null byte + ArrayList css = new ArrayList(); + css.add( "CSSCodec" ); + instance = new DefaultEncoder( css ); + System.out.println( "CSS Decoding" ); + assertEquals( "<", instance.canonicalize("\\3c")); // add strings to prevent null byte + assertEquals( "<", instance.canonicalize("\\03c")); + assertEquals( "<", instance.canonicalize("\\003c")); + assertEquals( "<", instance.canonicalize("\\0003c")); + assertEquals( "<", instance.canonicalize("\\00003c")); + assertEquals( "<", instance.canonicalize("\\3C")); + assertEquals( "<", instance.canonicalize("\\03C")); + assertEquals( "<", instance.canonicalize("\\003C")); + assertEquals( "<", instance.canonicalize("\\0003C")); + assertEquals( "<", instance.canonicalize("\\00003C")); + } + + + /** + * Test of canonicalize method, of class org.owasp.esapi.Encoder. + * + * @throws EncodingException + */ + public void testDoubleEncodingCanonicalization() throws EncodingException { + System.out.println("doubleEncodingCanonicalization"); + Encoder instance = ESAPI.encoder(); + + // note these examples use the strict=false flag on canonicalize to allow + // full decoding without throwing an IntrusionException. Generally, you + // should use strict mode as allowing double-encoding is an abomination. + + // double encoding examples + assertEquals( "<", instance.canonicalize("&lt;", false )); //double entity + assertEquals( "\\", instance.canonicalize("%255c", false)); //double percent + assertEquals( "%", instance.canonicalize("%2525", false)); //double percent + + // double encoding with multiple schemes example + assertEquals( "<", instance.canonicalize("%26lt%3b", false)); //first entity, then percent + assertEquals( "&", instance.canonicalize("%26", false)); //first percent, then entity + + //enforce multiple and mixed encoding detection + try { + instance.canonicalize("%26lt; %26lt; %3c %3c %2526lt%253B %2526lt%253B %2526lt%253B", true, true); + fail("Multiple and mixed encoding not detected"); + } catch (IntrusionException ie) {} + + //enforce multiple but not mixed encoding detection + try { + instance.canonicalize("%252525253C", true, false); + fail("Multiple encoding not detected"); + } catch (IntrusionException ie) {} + + //enforce mixed but not multiple encoding detection + try { + instance.canonicalize("%25 %2526 %26#X3c;script> %3Cscript%25252525253e", false, true); + fail("Mixed encoding not detected"); + } catch (IntrusionException ie) {} + + //enforce niether mixed nor multiple encoding detection -should canonicalize but not throw an error + assertEquals( "< < < < < < <", instance.canonicalize("%26lt; %26lt; %3c %3c %2526lt%253B %2526lt%253B %2526lt%253B", + false, false)); + + // nested encoding examples + assertEquals( "<", instance.canonicalize("%253c", false)); //nested encode % with percent + assertEquals( "<", instance.canonicalize("%%33%63", false)); //nested encode both nibbles with percent + assertEquals( "<", instance.canonicalize("%%33c", false)); // nested encode first nibble with percent + assertEquals( "<", instance.canonicalize("%3%63", false)); //nested encode second nibble with percent + assertEquals( "<", instance.canonicalize("&lt;", false)); //nested encode l with entity + assertEquals( "<", instance.canonicalize("%253c", false)); //triple percent, percent, 5 with entity + + // nested encoding with multiple schemes examples + assertEquals( "<", instance.canonicalize("&%6ct;", false)); // nested encode l with percent + assertEquals( "<", instance.canonicalize("%3c", false)); //nested encode 3 with entity + + // multiple encoding tests + assertEquals( "% & "); + request.addParameter("f2", ""); + request.addParameter("f3", ""); + for (int i = 1; i <= 4; i++) { + assertTrue(safeRequest.getParameter("p" + i).equals(request.getParameter("p" + i))); + } + for (int i = 1; i <= 2; i++) { + boolean testResult = false; + try { + testResult = safeRequest.getParameter("f" + i).equals(request.getParameter("f" + i)); + } catch (NullPointerException npe) { + //the test is this block SHOULD fail. a NPE is an acceptable failure state + testResult = false; //redundant, just being descriptive here + } + assertFalse(testResult); + } + assertNull(safeRequest.getParameter("e1")); + + //This is revealing problems with Jeff's original SafeRequest + //mishandling of the AllowNull parameter. I'm adding a new Google code + //bug to track this. + // + //assertNotNull(safeRequest.getParameter("e1", false)); + } + + @Test + public void testGetCookies() { +//testing Validator.HTTPCookieName and Validator.HTTPCookieValue + MockHttpServletRequest request = new MockHttpServletRequest(); + SecurityWrapperRequest safeRequest = new SecurityWrapperRequest(request); +//should support a base64-encode value + request.setCookie("p1", "34=VJhjv7jiDu7tsdLrQQ2KcUwpfWUM2_mBae6UA8ttk4wBHdxxQ-1IBxyCOn3LWE08SDhpnBcJ7N5Vze48F2t8a1R_hXt7PX1BvgTM0pn-T4JkqGTm_tlmV4RmU3GT-dgn"); + request.setCookie("f1", "XSS"); + request.setCookie("load-balancing", "pass"); + request.setCookie("'bypass", "fail"); + Cookie[] cookies = safeRequest.getCookies(); + assertEquals(cookies[0].getValue(), request.getCookies()[0].getValue()); + assertEquals(cookies[1].getName(), request.getCookies()[2].getName()); + assertEquals(2, cookies.length); + } + + @Test + public void testGetHeader() { +//testing Validator.HTTPHeaderValue + MockHttpServletRequest request = new MockHttpServletRequest(); + SecurityWrapperRequest safeRequest = new SecurityWrapperRequest(request); + request.addHeader("p1", "login"); + request.addHeader("f1", "XSS"); + request.addHeader("p2", TestUtils.generateStringOfLength(200)); // Upper limit increased from 150 -> 200, GitHub issue #351 + request.addHeader("f2", TestUtils.generateStringOfLength(4097)); + assertEquals(safeRequest.getHeader("p1"), request.getHeader("p1")); + assertEquals(safeRequest.getHeader("p2"), request.getHeader("p2")); + assertFalse(safeRequest.getHeader("f1").equals(request.getHeader("f1"))); + assertFalse(safeRequest.getHeader("f2").equals(request.getHeader("f2"))); + assertNull(safeRequest.getHeader("p3")); + } + + @Test + public void testHeaderLengthChecks(){ + Validator v = ESAPI.validator(); + SecurityConfiguration sc = ESAPI.securityConfiguration(); + assertFalse(v.isValidInput("addHeader", TestUtils.generateStringOfLength(257), "HTTPHeaderName", sc.getIntProp("HttpUtilities.MaxHeaderNameSize"), false)); + assertFalse(v.isValidInput("addHeader", TestUtils.generateStringOfLength(4097), "HTTPHeaderValue", sc.getIntProp("HttpUtilities.MaxHeaderValueSize"), false)); + } + + @Test + public void testGetHeaderNames() { +//testing Validator.HTTPHeaderName + MockHttpServletRequest request = new MockHttpServletRequest(); + SecurityWrapperRequest safeRequest = new SecurityWrapperRequest(request); + request.addHeader("d-49653-p", "pass"); + request.addHeader(""); + assertFalse(safeRequest.getQueryString().equals(request.getQueryString())); + request.setQueryString("mail=bob@alice.com-passwd=johny"); + assertTrue(safeRequest.getQueryString().equals(request.getQueryString())); + request.setQueryString("mail=bob@alice.com-passwd=johny&special"); //= is missing! + assertFalse(safeRequest.getQueryString().equals(request.getQueryString())); + } + + @Test + public void testGetRequestURI() { +//testing Validator.HTTPURI + MockHttpServletRequest request = new MockHttpServletRequest(); + SecurityWrapperRequest safeRequest = new SecurityWrapperRequest(request); + try { + request.setRequestURI("/app/page.jsp"); + } catch (UnsupportedEncodingException ignored) { + } + assertEquals(safeRequest.getRequestURI(), request.getRequestURI()); + } + + @Test + public void testGetContextPath() { + // Root Context Path ("") + assertTrue(ESAPI.validator().isValidInput("HTTPContextPath", "", "HTTPContextPath", 512, true)); + // Deployed Context Path ("/context") + assertTrue(ESAPI.validator().isValidInput("HTTPContextPath", "/context", "HTTPContextPath", 512, true)); + // Fail-case - URL Splitting + assertFalse(ESAPI.validator().isValidInput("HTTPContextPath", "/\\nGET http://evil.com", "HTTPContextPath", 512, true)); + } + + @Test + public void testGmailEmailAddress(){ + Validator v = ESAPI.validator(); + assertTrue(v.isValidInput("Gmail", "Darth+Sidious@gmail.com", "Gmail", 512, false)); + assertTrue(v.isValidInput("Gmail", "Darth.Sidious@gmail.com", "Gmail", 512, false)); + } + + @Test + public void testGetValidUri(){ + Validator v = ESAPI.validator(); + assertFalse(v.isValidURI("test", "http://core-jenkins.scansafe.cisco.com/ä˝č´şčŻşäĽ¦-^ńörĂ©n.jpg", false)); + } + + @Test + public void testGetValidUriNullInput(){ + Validator v = ESAPI.validator(); + boolean isValid = v.isValidURI("test", null, true); + assertTrue(isValid); + } + + @Test + public void testRegex(){ + Validator v = ESAPI.validator(); + boolean isValid = v.isValidInput("RegexString", "%2d%2d%3e%3c%2f%73%43%72%49%70%54%3e%3c%73%43%72%49%70%54%3e%61%6c%65%72%74%28%31%36%35%38%38%29%3c%2f%73%43%72%49%70%54%3e", "RegexString", 30000, true); + assertFalse(isValid); + } + + @Test(expected = ValidationException.class) + public void testRegexWithGetValid() throws IntrusionException, ValidationException { + Validator v = ESAPI.validator(); + String foo = v.getValidInput("RegexString", "%2d%2d%3e%3c%2f%73%43%72%49%70%54%3e%3c%73%43%72%49%70%54%3e%61%6c%65%72%74%28%31%36%35%38%38%29%3c%2f%73%43%72%49%70%54%3e", "RegexString", 30000, true); + } + + @Test + public void testavaloqLooseSafeString(){ + Validator v = ESAPI.validator(); + boolean isValid = v.isValidInput("RegexString", ""test"", "avaloqLooseSafeString", 2147483647, true, true); + assertFalse(isValid); + } +} diff --git a/src/test/java/org/owasp/esapi/reference/accesscontrol/AccessControllerTest.java b/src/test/java/org/owasp/esapi/reference/accesscontrol/AccessControllerTest.java new file mode 100644 index 000000000..9c4864cde --- /dev/null +++ b/src/test/java/org/owasp/esapi/reference/accesscontrol/AccessControllerTest.java @@ -0,0 +1,128 @@ +package org.owasp.esapi.reference.accesscontrol; + +import static org.junit.Assert.assertEquals; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Before; +import org.junit.Test; +import org.owasp.esapi.AccessController; +import org.owasp.esapi.errors.AccessControlException; +import org.owasp.esapi.reference.accesscontrol.AlwaysFalseACR; +import org.owasp.esapi.reference.accesscontrol.AlwaysTrueACR; +import org.owasp.esapi.reference.accesscontrol.ExperimentalAccessController; + +/** + * Answers the question: is the AccessController itself working properly? + * @author Mike H. Fauzy + * + */ +public class AccessControllerTest { + + protected AccessController accessController; + + @Before + public void setup() { + Map accessControlRules = new HashMap(3); + accessControlRules.put("AlwaysTrue", new AlwaysTrueACR()); + accessControlRules.put("AlwaysFalse", new AlwaysFalseACR()); + accessControlRules.put("EchoRuntimeParameter", new EchoRuntimeParameterACR()); + accessController = new ExperimentalAccessController(accessControlRules); + } + + @Test + public void isAuthorized() { + assertEquals("Rule Not Found: null", accessController.isAuthorized(null, null), false); + assertEquals("Rule Not Found: Invalid Key", accessController.isAuthorized("A key that does not map to a rule", null), false); + + assertEquals("AlwaysTrue", accessController.isAuthorized("AlwaysTrue", null), true); + assertEquals("AlwaysFalse", accessController.isAuthorized("AlwaysFalse", null), false); + + assertEquals("EchoRuntimeParameter: True", accessController.isAuthorized("EchoRuntimeParameter", Boolean.TRUE), true ); + assertEquals("EchoRuntimeParameter: False", accessController.isAuthorized("EchoRuntimeParameter", Boolean.FALSE), false); + assertEquals("EchoRuntimeParameter: ClassCastException", accessController.isAuthorized("EchoRuntimeParameter", "This is not a boolean"), false); + assertEquals("EchoRuntimeParameter: null Runtime Parameter", accessController.isAuthorized("EchoRuntimeParameter", null), false); + } + + @Test (expected = AccessControlException.class) + public void enforceAuthorizationRuleNotFoundNullKey() throws Exception { + accessController.assertAuthorized(null, null); + } + @Test (expected = AccessControlException.class) + public void enforceAuthorizationRuleAKeyThatDoesNotMapToARule() throws Exception { + accessController.assertAuthorized("A key that does not map to a rule", null); + } + + + @Test + //Should not throw an exception + public void enforceAuthorizationAlwaysTrue() throws Exception { + accessController.assertAuthorized("AlwaysTrue", null); + } + + @Test (expected = AccessControlException.class) + public void enforceAuthorizationAlwaysFalse() throws Exception { + accessController.assertAuthorized("AlwaysFalse", null); + } + + /** + * Ensure that isAuthorized does nothing if enforceAuthorization + * is called and isAuthorized returns true + */ + @Test + //Should not throw an exception + public void enforceAuthorizationEchoRuntimeParameterTrue() throws Exception { + accessController.assertAuthorized("EchoRuntimeParameter", Boolean.TRUE); + } + + /** + * Ensure that isAuthorized translates into an exception if enforceAuthorization + * is called and isAuthorized returns false + */ + @Test (expected = AccessControlException.class) + public void enforceAuthorizationEchoRuntimeParameterFalse() throws Exception { + accessController.assertAuthorized("EchoRuntimeParameter", Boolean.FALSE); + } + + @Test (expected = AccessControlException.class) + public void enforceAuthorizationEchoRuntimeParameterClassCastException() throws Exception { + accessController.assertAuthorized("EchoRuntimeParameter", "This is not a boolean"); + } + + @Test (expected = AccessControlException.class) + public void enforceAuthorizationEchoRuntimeParameterNullRuntimeParameter() throws Exception { + accessController.assertAuthorized("EchoRuntimeParameter", null); + } + + @org.junit.Test + public void delegatingACR() throws Exception { + DelegatingACR delegatingACR = new DelegatingACR(); + DynaBeanACRParameter policyParameter = new DynaBeanACRParameter(); + + delegatingACR = new DelegatingACR(); + policyParameter = new DynaBeanACRParameter(); + policyParameter.set("delegateClass", "java.lang.Object"); + policyParameter.set("delegateMethod", "equals"); + policyParameter.set("parameterClasses", new String[] {"java.lang.Object"}); + delegatingACR.setPolicyParameters(policyParameter); + org.junit.Assert.assertFalse(delegatingACR.isAuthorized(new Object[] {new Object()})); + org.junit.Assert.assertFalse(delegatingACR.isAuthorized(new Object[] {delegatingACR})); + + + policyParameter.set("delegateClass", "org.owasp.esapi.reference.accesscontrol.AlwaysTrueACR"); + policyParameter.set("delegateMethod", "isAuthorized"); + policyParameter.set("parameterClasses", new String[] {"java.lang.Object"}); + delegatingACR.setPolicyParameters(policyParameter); + org.junit.Assert.assertTrue(delegatingACR.isAuthorized(new Object[] {null})); + + delegatingACR = new DelegatingACR(); + policyParameter = new DynaBeanACRParameter(); + policyParameter.set("delegateClass", "org.owasp.esapi.reference.accesscontrol.AlwaysFalseACR"); + policyParameter.set("delegateMethod", "isAuthorized"); + policyParameter.set("parameterClasses", new String[] {"java.lang.Object"}); + delegatingACR.setPolicyParameters(policyParameter); + org.junit.Assert.assertFalse(delegatingACR.isAuthorized(new Object[] {null})); + } + +} diff --git a/src/test/java/org/owasp/esapi/reference/accesscontrol/policyloader/ACRPolicyFileLoaderTest.java b/src/test/java/org/owasp/esapi/reference/accesscontrol/policyloader/ACRPolicyFileLoaderTest.java new file mode 100644 index 000000000..a8d4394d1 --- /dev/null +++ b/src/test/java/org/owasp/esapi/reference/accesscontrol/policyloader/ACRPolicyFileLoaderTest.java @@ -0,0 +1,70 @@ +package org.owasp.esapi.reference.accesscontrol.policyloader; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Map; + +import org.junit.Before; +import org.junit.Test; +import org.owasp.esapi.AccessController; +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.errors.AccessControlException; +/** + * Answers the question: Is the policy file being loaded properly? + * @author Mike H. Fauzy + */ +public class ACRPolicyFileLoaderTest { + + protected AccessController accessController; + + @Before + public void setUp() throws Exception { + accessController = ESAPI.accessController(); + } + + @Test + public void testSetup() throws AccessControlException { + /** + * This tests the policy file + */ + ACRPolicyFileLoader policyDescriptor = new ACRPolicyFileLoader(); + PolicyDTO policyDTO = policyDescriptor.load(); + Map accessControlRules = policyDTO.getAccessControlRules(); + assertTrue("Some AccessControlRules are loaded", !accessControlRules + .isEmpty()); + assertTrue("Access Control Map Contains AlwaysTrue", accessControlRules + .containsKey("AlwaysTrue")); + assertTrue("Access Control Map Contains AlwaysFalse", + accessControlRules.containsKey("AlwaysFalse")); + assertTrue("Access Control Map Contains EchoRuntimeParameter", + accessControlRules.containsKey("EchoRuntimeParameter")); + assertTrue("Access Control Map Contains EchoPolicyParameter", + accessControlRules.containsKey("EchoPolicyParameter")); + } + + @Test + public void isAuthorizedEchoPolicyParameter() { + assertEquals("EchoPolicyParameter", accessController + .isAuthorized("EchoPolicyParameter", null), true); + assertEquals("EchoRuntimeParameterClassCastException", accessController + .isAuthorized("EchoRuntimeParameterClassCastException", null), + false); + // Policy parameter value null, empty or missing. (TODO add more fail + // state tests + // assertEquals("EchoRuntimeParameterValueNull", + // accessController.isAuthorized("EchoRuntimeParameterValueNull", null), + // false); + // assertEquals("EchoRuntimeParameterValueEmpty", + // accessController.isAuthorized("EchoRuntimeParameterValueEmpty", + // null), false); + // assertEquals("EchoRuntimeParameterValueMissing", + // accessController.isAuthorized("EchoRuntimeParameterValueMissing", + // null), false); + } + + @Test(expected = AccessControlException.class) + public void enforceAuthorizationRuleNotFoundNullKey() throws AccessControlException { + accessController.assertAuthorized(null, null); + } +} diff --git a/src/test/java/org/owasp/esapi/reference/crypto/CryptoPolicy.java b/src/test/java/org/owasp/esapi/reference/crypto/CryptoPolicy.java new file mode 100644 index 000000000..f679f4c83 --- /dev/null +++ b/src/test/java/org/owasp/esapi/reference/crypto/CryptoPolicy.java @@ -0,0 +1,105 @@ +package org.owasp.esapi.reference.crypto; + +import java.security.*; +import javax.crypto.*; +import javax.crypto.spec.*; + +/** + * Helper class to see if unlimited strength crypto is available. If it is + * not, then symmetric encryption algorithms are restricted to 128-bit + * key size or the encryption must provide key weakening or key escrow. + *

+ * This program attempts to generate a 256-bit AES key and use it to do + * to a simple encryption. If the encryption succeeds, the assumption is + * that the JVM being used has the "unlimited" strength JCE jurisdiction + * policy files installed. + *

+ * We use this for JUnit tests. If unlimited strength crypto is not available, + * we simply skip certain JUnit tests that would require it. + *

+ * The reason for not adding this class to ESAPI proper is because its mostly + * pointless to find out at runtime that you don't have the unlimited strength + * JCE jurisdiction policy files installed. If you don't, you're SOL until you + * install them and even if you could do that from a running JVM, chances are + * slim to none that one could easily get your JCE provider to work with them. + * (Well, one might be able to unload the JCE classes, but you hopefully + * are not running your JVM process as 'root' or other privileged account + * anyway, so you probably can't install these policy files from your JVM in + * the first place.) + *

+ * @author kevin.w.wall@gmail.com + * @since 2.0 + */ +public class CryptoPolicy { + + private static boolean checked = false; + private static boolean unlimited = false; + + /** + * Check to see if unlimited strength crypto is available. + * There is an implicit assumption that the JCE jurisdiction policy + * files are not going to be changing while this given JVM is running. + * + * @return True if we can provide keys longer than 128 bits. + */ + public synchronized static boolean isUnlimitedStrengthCryptoAvailable() + { + if ( checked == false ) { + unlimited = checkCrypto(); + checked = true; + } + return unlimited; + } + + private static boolean checkCrypto() + { + try { + KeyGenerator keyGen = KeyGenerator.getInstance("AES"); + keyGen.init(256); // Max sym key size is 128 unless unlimited + // strength jurisdiction policy files installed. + SecretKey skey = keyGen.generateKey(); + byte[] raw = skey.getEncoded(); + SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); + Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding"); + + // This usually will throw InvalidKeyException unless the + // unlimited jurisdiction policy files are installed. However, + // it can succeed even if it's not a provider chooses to use + // an exemption mechanism such as key escrow, key recovery, or + // key weakening for this cipher instead. + cipher.init(Cipher.ENCRYPT_MODE, skeySpec); + + // Try the encryption on dummy string to make sure it works. + // Not using padding so # bytes must be multiple of AES cipher + // block size which is 16 bytes. Also, OK not to use UTF-8 here. + byte[] encrypted = cipher.doFinal("1234567890123456".getBytes()); + assert encrypted != null : "Encryption of test string failed!"; + ExemptionMechanism em = cipher.getExemptionMechanism(); + if ( em != null ) { + System.out.println("Cipher uses exemption mechanism " + em.getName()); + return false; // This is actually an indeterminate case, but + // we can't bank on it at least for this + // (default) provider. + } + } catch( InvalidKeyException ikex ) { + System.out.println("CryptoPolicy: 256 bits is " + + "invalid key size ==> unlimited strength crypto NOT installed!"); + return false; + } catch( Exception ex ) { + System.out.println("Caught unexpected exception: " + ex); + ex.printStackTrace(System.out); + return false; + } + return true; + } + + public static void main(String[] args) + { + if ( isUnlimitedStrengthCryptoAvailable() ) { + System.out.println("Unlimited strength crypto IS available."); + } else { + System.out.println("Unlimited strength crypto is NOT available."); + } + System.exit( isUnlimitedStrengthCryptoAvailable() ? 0 : 1 ); + } +} \ No newline at end of file diff --git a/src/test/java/org/owasp/esapi/reference/crypto/EncryptedPropertiesTest.java b/src/test/java/org/owasp/esapi/reference/crypto/EncryptedPropertiesTest.java new file mode 100644 index 000000000..0f7882bd3 --- /dev/null +++ b/src/test/java/org/owasp/esapi/reference/crypto/EncryptedPropertiesTest.java @@ -0,0 +1,232 @@ +/** + * 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.reference.crypto; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.StringBufferInputStream; +import java.util.Iterator; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.errors.EncryptionException; +import org.owasp.esapi.reference.crypto.DefaultEncryptedProperties; + +/** + * The Class EncryptedPropertiesTest. + * + * @author Jeff Williams (jeff.williams@aspectsecurity.com) + */ +public class EncryptedPropertiesTest extends TestCase { + + /** + * Instantiates a new encrypted properties test. + * + * @param testName + * the test name + */ + public EncryptedPropertiesTest(String testName) { + super(testName); + } + + /** + * {@inheritDoc} + */ + protected void setUp() throws Exception { + // none + } + + /** + * {@inheritDoc} + */ + protected void tearDown() throws Exception { + // none + } + + /** + * Suite. + * + * @return the test + */ + public static Test suite() { + TestSuite suite = new TestSuite(EncryptedPropertiesTest.class); + + return suite; + } + + /** + * Test of getProperty method, of class org.owasp.esapi.EncryptedProperties. + * + * @throws EncryptionException + * the encryption exception + */ + public void testGetProperty() throws EncryptionException { + System.out.println("getProperty"); + DefaultEncryptedProperties instance = new DefaultEncryptedProperties(); + String name = "name"; + String value = "value"; + instance.setProperty(name, value); + String result = instance.getProperty(name); + assertEquals(value, result); + assertNull(instance.getProperty("ridiculous")); + } + + /** + * Test of setProperty method, of class org.owasp.esapi.EncryptedProperties. + * + * @throws EncryptionException + * the encryption exception + */ + public void testSetProperty() throws EncryptionException { + System.out.println("setProperty"); + DefaultEncryptedProperties instance = new DefaultEncryptedProperties(); + String name = "name"; + String value = "value"; + instance.setProperty(name, value); + String result = instance.getProperty(name); + assertEquals(value, result); + + instance.setProperty(name, ""); + result = instance.getProperty(name); + assertEquals(result, ""); + + try { + instance.setProperty(null, value); + fail("testSetProperty(): Null property name did not result in expected exception."); + } catch( Exception e ) { + assertTrue( e instanceof EncryptionException ); + } + try { + instance.setProperty(name, null); + fail("testSetProperty(): Null property value did not result in expected exception."); + } catch( Exception e ) { + assertTrue( e instanceof EncryptionException ); + } + try { + instance.setProperty(null, null); + fail("testSetProperty(): Null property name and valud did not result in expected exception."); + } catch( Exception e ) { + assertTrue( e instanceof EncryptionException ); + } + } + + /** + * Test the behavior when the requested key does not exist. + */ + public void testNonExistantKeyValue() throws Exception + { + DefaultEncryptedProperties instance = new DefaultEncryptedProperties(); + assertNull(instance.getProperty("not.there")); + } + + /** + * Test of keySet method, of class org.owasp.esapi.EncryptedProperties. + */ + public void testKeySet() throws Exception + { + boolean sawTwo = false; + boolean sawOne = false; + + System.out.println("keySet"); + DefaultEncryptedProperties instance = new DefaultEncryptedProperties(); + instance.setProperty("one", "two"); + instance.setProperty("two", "three"); + Iterator i = instance.keySet().iterator(); + while(i.hasNext()) + { + String key = (String)i.next(); + + assertNotNull("key returned from keySet() iterator was null", key); + if(key.equals("one")) + if(sawOne) + fail("Key one seen more than once."); + else + sawOne = true; + else if(key.equals("two")) + if(sawTwo) + fail("Key two seen more than once."); + else + sawTwo = true; + else + fail("Unset key " + key + " returned from keySet().iterator()"); + } + assertTrue("Key one was never seen", sawOne); + assertTrue("Key two was never seen", sawTwo); + } + + /** + * Test storing and loading of encrypted properties. + */ + public void testStoreLoad() throws Exception + { + DefaultEncryptedProperties toLoad = new DefaultEncryptedProperties(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ByteArrayInputStream bais; + boolean sawOne = false; + boolean sawTwo = false; + boolean sawSeuss = false; + + DefaultEncryptedProperties toStore = new DefaultEncryptedProperties(); + toStore.setProperty("one", "two"); + toStore.setProperty("two", "three"); + toStore.setProperty("seuss.schneier", "one fish, twofish, red fish, blowfish"); + toStore.store(baos, "testStore"); + + bais = new ByteArrayInputStream(baos.toByteArray()); + toLoad.load(bais); + + for(Iterator i=toLoad.keySet().iterator();i.hasNext();) + { + String key = (String)i.next(); + + assertNotNull("key returned from keySet() iterator was null", key); + if(key.equals("one")) + if(sawOne) + fail("Key one seen more than once."); + else + { + sawOne = true; + assertEquals("Key one's value was not two", "two", toLoad.getProperty("one")); + } + else if(key.equals("two")) + if(sawTwo) + fail("Key two seen more than once."); + else + { + sawTwo = true; + assertEquals("Key two's value was not three", "three", toLoad.getProperty("two")); + } + else if(key.equals("seuss.schneier")) + if(sawSeuss) + fail("Key seuss.schneier seen more than once."); + else + { + sawSeuss = true; + assertEquals("Key seuss.schneier's value was not expected value", + "one fish, twofish, red fish, blowfish", + toStore.getProperty("seuss.schneier")); + } + else + fail("Unset key " + key + " returned from keySet().iterator()"); + } + assertTrue("Key one was never seen", sawOne); + assertTrue("Key two was never seen", sawTwo); + } +} diff --git a/src/test/java/org/owasp/esapi/reference/crypto/EncryptedPropertiesUtilsTest.java b/src/test/java/org/owasp/esapi/reference/crypto/EncryptedPropertiesUtilsTest.java new file mode 100644 index 000000000..124e289b8 --- /dev/null +++ b/src/test/java/org/owasp/esapi/reference/crypto/EncryptedPropertiesUtilsTest.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.reference.crypto; + +import static org.junit.Assert.*; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.util.Properties; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.rules.TestName; + + +/** + * The Class EncryptedPropertiesTest. + * + * @author August Detlefsen (augustd at codemagi dot com) + * CodeMagi, Inc. + * @since October 8, 2010 + */ +public class EncryptedPropertiesUtilsTest { + + private static final String KEY1 = "quick"; + private static final String VALUE1 = "brown fox"; + private static final String KEY2 = "jumps"; + private static final String VALUE2 = "lazy dog"; + private static final String KEY3 = "joe bob"; + private static final String VALUE3 = "jim bob"; + private static final String KEY4 = "sally sue"; + private static final String VALUE4 = "betty mae"; + + + /** Rule to acquire the running test's information at runtime.*/ + @Rule + public TestName testName = new TestName(); + + /** File management component for IO targets during test executions.*/ + @Rule + public TemporaryFolder tempFolder = new TemporaryFolder(); + + /** Counter used to track the number of files created for a single test to assist with creating unique file references.*/ + private int fileIndex = 0; + + /** + * Creates a new properties file reference for the active test which will be cleaned up upon test completion. + * @return File New unique file reference for the active test. + * @throws IOException If a new file could not be generated. + */ + private final File getTempPropertiesFile() throws IOException { + return tempFolder.newFile(String.format("%s_%2d.properties", testName.getMethodName(), fileIndex++)); + } + /** + * Test of creating and storing a new EncryptedProperties from scratch, + * as if calling: + * + * EncryptedPropertiesUtils --out encrypted.properties + * + * + * @throws Exception Any exception that occurs + */ + @Test public void testCreateNew() throws Exception { + File encryptedFile = getTempPropertiesFile(); + + //create a new properties with no input + Properties props = EncryptedPropertiesUtils.loadProperties(null, null); + + //add some properties + Object prop1 = EncryptedPropertiesUtils.addProperty(props, KEY1, VALUE1); + assertNull("Expected null but returned: " + prop1, prop1); + + Object prop2 = EncryptedPropertiesUtils.addProperty(props, KEY2, VALUE2); + assertNull("Expected null but returned: " + prop2, prop2); + + //store the file + EncryptedPropertiesUtils.storeProperties(encryptedFile.getAbsolutePath(), props, "Encrypted Properties File generated by EncryptedPropertiesUtilsTest"); + + //try reading in the resulting file + ReferenceEncryptedProperties loadedProps = new ReferenceEncryptedProperties(); + loadedProps.load(new FileReader(encryptedFile.getAbsolutePath())); + + assertEquals(VALUE1, loadedProps.getProperty(KEY1)); + assertEquals(VALUE2, loadedProps.getProperty(KEY2)); + } + + /** + * Test of loading a plaintext file and storing it as an encrypted properties file, + * as if calling: + * + * EncryptedPropertiesUtils --in plaintext.properties --out encrypted.properties --in-encrypted false + * + * + * @throws Exception Any exception that occurs + */ + @Test public void testLoadPlaintextAndEncrypt() throws Exception { + File encryptedFile = getTempPropertiesFile(); + File plainTextFile = getTempPropertiesFile(); + + //write an initial plaintext properties file + Properties props = new Properties(); + props.setProperty(KEY3, VALUE3); + props.setProperty(KEY4, VALUE4); + + props.store(new FileOutputStream(plainTextFile.getAbsolutePath()), "Plaintext test file created by EncryptedPropertiesUtilsTest"); + + //load the plaintext properties file + props = EncryptedPropertiesUtils.loadProperties(plainTextFile.getAbsolutePath(), false); + + //test some properties using getProperty + assertEquals(VALUE3, props.getProperty(KEY3)); + assertEquals(VALUE4, props.getProperty(KEY4)); + + //store the file + EncryptedPropertiesUtils.storeProperties(encryptedFile.getAbsolutePath(), props, "Encrypted Properties File generated by EncryptedPropertiesUtilsTest"); + + //try reading in the resulting file + ReferenceEncryptedProperties loadedProps = new ReferenceEncryptedProperties(); + loadedProps.load(new FileReader(encryptedFile.getAbsolutePath())); + + assertEquals(VALUE3, loadedProps.getProperty(KEY3)); + assertEquals(VALUE4, loadedProps.getProperty(KEY4)); + } + + /** + * Test of loading an encrypted file, adding new properties and storing it as an encrypted properties file, + * as if calling: + * + * EncryptedPropertiesUtils --in encrypted.properties --out encrypted.2.properties + * + * + * @throws Exception Any exception that occurs + */ + @Test public void testLoadEncryptedAndAdd() throws Exception { + File encryptedFile = getTempPropertiesFile(); + File encryptedFile2 = getTempPropertiesFile(); + //load the plaintext properties file + Properties props = EncryptedPropertiesUtils.loadProperties(encryptedFile.getAbsolutePath(), true); + + //add some new properties + EncryptedPropertiesUtils.addProperty(props, KEY1, VALUE1); + EncryptedPropertiesUtils.addProperty(props, KEY2, VALUE2); + + //test the newly added properties + assertEquals(VALUE1, props.getProperty(KEY1)); + assertEquals(VALUE2, props.getProperty(KEY2)); + + //store the file + EncryptedPropertiesUtils.storeProperties(encryptedFile2.getAbsolutePath(), props, "Encrypted Properties File generated by EncryptedPropertiesUtilsTest"); + + //try reading in the resulting file + ReferenceEncryptedProperties loadedProps = new ReferenceEncryptedProperties(); + loadedProps.load(new FileReader(encryptedFile2.getAbsolutePath())); + + //test the values read in + assertEquals(VALUE1, loadedProps.getProperty(KEY1)); + assertEquals(VALUE2, loadedProps.getProperty(KEY2)); + } + +} diff --git a/src/test/java/org/owasp/esapi/reference/crypto/EncryptorTest.java b/src/test/java/org/owasp/esapi/reference/crypto/EncryptorTest.java new file mode 100644 index 000000000..08819d175 --- /dev/null +++ b/src/test/java/org/owasp/esapi/reference/crypto/EncryptorTest.java @@ -0,0 +1,599 @@ +/** + * 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.reference.crypto; + +import java.io.UnsupportedEncodingException; + +import javax.crypto.SecretKey; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.EncoderConstants; +import org.owasp.esapi.Encryptor; +import org.owasp.esapi.crypto.CipherText; +import org.owasp.esapi.crypto.CryptoHelper; +import org.owasp.esapi.crypto.PlainText; +import org.owasp.esapi.errors.EncryptionException; +import org.owasp.esapi.errors.EnterpriseSecurityException; +import org.owasp.esapi.errors.IntegrityException; +import org.owasp.esapi.reference.crypto.JavaEncryptor; + +/** + * The Class EncryptorTest. + * + * @author Jeff Williams (jeff.williams@aspectsecurity.com) + * @author kevin.w.wall@gmail.com + */ +public class EncryptorTest extends TestCase { + + public static boolean unlimitedStrengthJurisdictionPolicyInstalled = false; + static { + try { + unlimitedStrengthJurisdictionPolicyInstalled = CryptoPolicy.isUnlimitedStrengthCryptoAvailable(); + } catch(Throwable t) { + ; // Intentionally ignore (but really shouldn't happen unless Error thrown) and we don't want to bail in that case anyhow + } finally { + System.out.println("EncryptorTest: Strong crypto tests " + + ( unlimitedStrengthJurisdictionPolicyInstalled ? "will not" : "will" ) + + " be skipped."); + } + } + + /** + * Instantiates a new encryptor test. + * + * @param testName + * the test name + */ + public EncryptorTest(String testName) { + super(testName); + } + + /** + * {@inheritDoc} + * @throws Exception + */ + @SuppressWarnings("deprecation") + protected void setUp() throws Exception { + // This is only mechanism to change this for now. Will do this with + // a soon to be CryptoControls class or equivalent mechanism in a + // future release. + ESAPI.securityConfiguration().setCipherTransformation("AES/CBC/PKCS5Padding"); + } + + /** + * {@inheritDoc} + * @throws Exception + */ + protected void tearDown() throws Exception { + // none + } + + /** + * Run all the test cases in this suite. + * This is to allow running from {@code org.owasp.esapi.AllTests}. + * + * @return the test + */ + public static Test suite() { + TestSuite suite = new TestSuite(EncryptorTest.class); + + return suite; + } + + /** + * Test of hash method, of class org.owasp.esapi.Encryptor. + * + * @throws EncryptionException + */ + public void testHash() throws EncryptionException { + System.out.println("testHash()"); + Encryptor instance = ESAPI.encryptor(); + String hash1 = instance.hash("test1", "salt"); + String hash2 = instance.hash("test2", "salt"); + assertFalse(hash1.equals(hash2)); + String hash3 = instance.hash("test", "salt1"); + String hash4 = instance.hash("test", "salt2"); + assertFalse(hash3.equals(hash4)); + } + + /** + * Test of new encrypt / decrypt method for Strings whose length is + * not a multiple of the cipher block size (16 bytes for AES). + * + * @throws EncryptionException + * the encryption exception + */ + public void testEncryptDecrypt1() throws EncryptionException { + System.out.println("testEncryptDecrypt2()"); + Encryptor instance = ESAPI.encryptor(); + String plaintext = "test1234test1234tes"; // Not a multiple of block size (16 bytes) + try { + CipherText ct = instance.encrypt(new PlainText(plaintext)); + PlainText pt = instance.decrypt(ct); + assertTrue( pt.toString().equals(plaintext) ); + } + catch( EncryptionException e ) { + fail("testEncryptDecrypt2(): Caught exception: " + e); + } + } + + /** + * Test of new encrypt / decrypt method for Strings whose length is + * same as cipher block size (16 bytes for AES). + */ + public void testEncryptDecrypt2() { + System.out.println("testEncryptDecrypt2()"); + Encryptor instance = ESAPI.encryptor(); + String plaintext = "test1234test1234"; + try { + CipherText ct = instance.encrypt(new PlainText(plaintext)); + PlainText pt = instance.decrypt(ct); + assertTrue( pt.toString().equals(plaintext) ); + } + catch( EncryptionException e ) { + fail("testEncryptDecrypt2(): Caught exception: " + e); + } + } + + /** + * Test of encrypt methods for empty String. + */ + public void testEncryptEmptyStrings() { + System.out.println("testEncryptEmptyStrings()"); + Encryptor instance = ESAPI.encryptor(); + String plaintext = ""; + try { + // System.out.println("New encryption methods"); + CipherText ct = instance.encrypt(new PlainText(plaintext)); + PlainText pt = instance.decrypt(ct); + assertTrue( pt.toString().equals("") ); + } catch(Exception e) { + fail("testEncryptEmptyStrings() -- Caught exception: " + e); + } + } + + /** + * Test encryption method for null. + */ + public void testEncryptNull() { + System.out.println("testEncryptNull()"); + Encryptor instance = ESAPI.encryptor(); + try { + CipherText ct = instance.encrypt( null ); // Should throw NPE or AssertionError + fail("New encrypt(PlainText) method did not throw. Result was: " + ct.toString()); + } catch(Throwable t) { + // It should be one of these, depending on whether or not assertions are enabled. + assertTrue( t instanceof IllegalArgumentException || t instanceof AssertionError); + } + } + + /** + * Test decryption method for null. + */ + public void testDecryptNull() { + System.out.println("testDecryptNull()"); + Encryptor instance = ESAPI.encryptor(); + try { + PlainText pt = instance.decrypt( null ); // Should throw IllegalArgumentException or AssertionError + fail("New decrypt(PlainText) method did not throw. Result was: " + pt.toString()); + } catch(Throwable t) { + // It should be one of these, depending on whether or not assertions are enabled. + assertTrue( t instanceof IllegalArgumentException || t instanceof AssertionError); + } + } + + /** + * Test of new encrypt / decrypt methods added in ESAPI 2.0. + */ + public void testNewEncryptDecrypt() { + System.out.println("testNewEncryptDecrypt()"); + try { + // Let's try it with a 2-key version of 3DES. This should work for all + // installations, whereas the 3-key Triple DES will only work for those + // who have the Unlimited Strength Jurisdiction Policy files installed. + runNewEncryptDecryptTestCase("DESede/CBC/PKCS5Padding", 112, "1234567890".getBytes("UTF-8")); + runNewEncryptDecryptTestCase("DESede/CBC/NoPadding", 112, "12345678".getBytes("UTF-8")); + + runNewEncryptDecryptTestCase("AES/CBC/PKCS5Padding", 128, "Encrypt the world!".getBytes("UTF-8")); + + // These tests are only valid (and run) if one has the JCE Unlimited + // Strength Jurisdiction Policy files installed for this Java VM. + // 256-bit AES + runNewEncryptDecryptTestCase("AES/ECB/NoPadding", 256, "test1234test1234".getBytes("UTF-8")); + // 168-bit (aka, 3-key) Triple DES + runNewEncryptDecryptTestCase("DESede/CBC/PKCS5Padding", 168, "Groucho's secret word".getBytes("UTF-8")); + } catch (UnsupportedEncodingException e) { + fail("OK, who stole UTF-8 encoding from the Java rt.jar ???"); + } + + } + + /** Special encryption case!!! Test encryption with DES, which has a key less than the + * min key size specified as Encryptor.EncryptionKeyLength in the file + * src/test/resources/esapi/ESAPI.properties. + */ + public void testWithTooShortKey() { + boolean desTestFailed = false; + try { + // We expect this one to throw because we have: + // Encryptor.EncryptionKeyLength=112 + // set in src/test/resources/esapi/ESAPI.properties. It should throw + // an EncryptionException (with a cause of ConfigurationException). + + // Generate an appropriate random secret key + SecretKey skey = CryptoHelper.generateSecretKey("DES/ECB/NoPadding", 56); + + // Change to different cipher. (Default is AES.) This is kludgey at best. Am thinking about an + // alternate way to do this using a new 'CryptoControls' class. Maybe not until release 2.1. + // Change the cipher transform from whatever it currently is to the specified cipherXform. + @SuppressWarnings("deprecation") + String oldCipherXform = ESAPI.securityConfiguration().setCipherTransformation("DES/ECB/NoPadding"); + + // Get an Encryptor instance with the specified, new, cipher transformation. + Encryptor instance = ESAPI.encryptor(); + PlainText plaintext = new PlainText( "test1234".getBytes("UTF-8") ); + + // Do the encryption with the new encrypt() method and get back the CipherText. + // This should throw because the key is too short. + CipherText ciphertext = instance.encrypt(skey, plaintext); // The new encrypt() method. Should throw! + + } catch ( EncryptionException eex ) { + desTestFailed = true; + } catch ( Exception ex ) { + fail("testWithTooShortKey(): Caught unexpected exception; msg was: " + ex); + } + + assertTrue( + "Expected 56-key DES to throw EncryptionException; " + + "check Encryptor.EncryptionKeyLength in src/test/resources/esapi/ESAPI.properties file.", + desTestFailed); + } + + /** + * Helper method to test new encryption / decryption. + * @param cipherXform Cipher transformation + * @param keySize Size of key, in bits. + * @param plaintextBytes Byte array of plaintext. + * @return The base64-encoded IV+ciphertext (or just ciphertext if no IV) or + * null if {@code keysize} is greater than 128 bits and unlimited + * strength crypto is not available for this Java VM. + */ + private String runNewEncryptDecryptTestCase(String cipherXform, int keySize, byte[] plaintextBytes) { + // System.err.println("New encrypt / decrypt: " + cipherXform + "; requested key size: " + keySize + " bits."); + + if ( keySize > 128 && !unlimitedStrengthJurisdictionPolicyInstalled ) { + System.err.println("Skipping test for cipher transformation " + + cipherXform + " with key size of " + keySize + + " bits because this requires JCE Unlimited Strength" + + " Jurisdiction Policy files to be installed and they" + + " are not."); + return null; + } + + try { + // Generate an appropriate random secret key + SecretKey skey = CryptoHelper.generateSecretKey(cipherXform, keySize); + assertTrue( skey.getAlgorithm().equals(cipherXform.split("/")[0]) ); + String cipherAlg = cipherXform.split("/")[0]; + + // System.err.println("Key size of generated encoded key: " + skey.getEncoded().length * 8 + " bits."); + + // Adjust key size for DES and DESede specific oddities. + // NOTE: Key size that encrypt() method is using is 192 bits!!! + // which is 3 times 64 bits, but DES key size is only 56 bits. + // See 'IMPORTANT NOTE', in JavaEncryptor, near line 376. It's a "feature"!!! +///// This section is causing problems. BC for instance sometimes creates a +///// 192 bit key and then subsequently creates a 128-bit key for 2-key +///// 3DES so adjusing this is futile. THis is a holdover when we were +///// doing an *exact* size comparison in the following assertTrue() though. +///// Since we are no longer doing that, we don't need to "adjust" the size +///// so hopefully all will be well with the world. +///// +///// Delete this comment and the following commented-out code after the +///// official 2.2.0.0 release. +///// +/* + if ( cipherAlg.equals( "DESede" ) ) { + System.err.println("Adjusting requested key size of " + keySize + " bits to 192 bits for DESede"); + keySize = 192; + } else if ( cipherAlg.equals( "DES" ) ) { + System.err.println("Adjusting requested key size of " + keySize + " bits to 64 bits for DES"); + keySize = 64; + } // Else... use specified keySize. + */ + + assertTrue(cipherXform + ": encoded key size of " + skey.getEncoded().length + " shorter than requested key size of: " + (keySize / 8), + skey.getEncoded().length >= (keySize / 8) ); + + // Change to a possibly different cipher. This is kludgey at best. Am thinking about an + // alternate way to do this using a new 'CryptoControls' class. Maybe not until release 2.1. + // Change the cipher transform from whatever it currently is to the specified cipherXform. + @SuppressWarnings("deprecation") + String oldCipherXform = ESAPI.securityConfiguration().setCipherTransformation(cipherXform); +/* + if ( ! cipherXform.equals(oldCipherXform) ) { + System.err.println("Cipher xform changed from \"" + oldCipherXform + "\" to \"" + cipherXform + "\""); + } + */ + + // Get an Encryptor instance with the specified, possibly new, cipher transformation. + Encryptor instance = ESAPI.encryptor(); + PlainText plaintext = new PlainText(plaintextBytes); + PlainText origPlainText = new PlainText( plaintext.toString() ); // Make _copy_ of original for comparison. + + // Do the encryption with the new encrypt() method and get back the CipherText. + CipherText ciphertext = instance.encrypt(skey, plaintext); // The new encrypt() method. + System.err.println("DEBUG: Encrypt(): CipherText object is -- " + ciphertext); + assertNotNull( ciphertext ); +// System.err.println("DEBUG: After encryption: base64-encoded IV+ciphertext: " + ciphertext.getEncodedIVCipherText()); +// System.err.println("\t\tOr... " + ESAPI.encoder().decodeFromBase64(ciphertext.getEncodedIVCipherText()) ); +// System.err.println("DEBUG: After encryption: base64-encoded raw ciphertext: " + ciphertext.getBase64EncodedRawCipherText()); +// System.err.println("\t\tOr... " + ESAPI.encoder().decodeFromBase64(ciphertext.getBase64EncodedRawCipherText()) ); + + // If we are supposed to have overwritten the plaintext, check this to see + // if origPlainText was indeed overwritten. + @SuppressWarnings("deprecation") + boolean overwritePlaintext = ESAPI.securityConfiguration().overwritePlainText(); + if ( overwritePlaintext ) { + assertTrue( isPlaintextOverwritten(plaintext) ); + } + + // Take the resulting ciphertext and decrypt w/ new decryption method. + PlainText decryptedPlaintext = instance.decrypt(skey, ciphertext); // The new decrypt() method. + + // Make sure we got back the same thing we started with. + System.out.println("\tOriginal plaintext: " + origPlainText); + System.out.println("\tResult after decryption: " + decryptedPlaintext); + assertEquals( "Failed to decrypt properly.", origPlainText.toString(), decryptedPlaintext.toString() ); + + // Restore the previous cipher transformation. For now, this is only way to do this. + @SuppressWarnings("deprecation") + String previousCipherXform = ESAPI.securityConfiguration().setCipherTransformation(null); + assertEquals( previousCipherXform, cipherXform ); + @SuppressWarnings("deprecation") + String defaultCipherXform = ESAPI.securityConfiguration().getCipherTransformation(); + assertEquals( defaultCipherXform, oldCipherXform ); + + return ciphertext.getEncodedIVCipherText(); + } catch (Exception e) { + // OK if not counted toward code coverage. + System.out.println("testNewEncryptDecrypt(): Caught unexpected exception: " + e.getClass().getName()); + e.printStackTrace(System.out); + fail("Caught unexpected exception; msg was: " + e); + } + return null; + } + + private static boolean isPlaintextOverwritten(PlainText plaintext) { + // Note: An assumption here that the original plaintext did not consist + // entirely of all '*' characters. + byte[] ptBytes = plaintext.asBytes(); + + for ( int i = 0; i < ptBytes.length; i++ ) { + if ( ptBytes[i] != '*' ) { + return false; + } + } + return true; + } + + // TODO - Because none of the encryption / decryption tests persists + // encrypted data across runs, that means everything is run + // under same JVM at same time thus always with the same + // _native_ byte encoding. + // + // Need test(s) such that data is persisted across JVM runs + // so we can test a run on (say) a Windows Intel box can decrypt + // encrypted data produced by the reference Encryptor on + // (say) a Solaris SPARC box. I.e., test that the change to + // JavaEncryptor to use UTF-8 encoding throughout works as + // desired. + // + // Files saved across tests need to be added to SVN (under + // resources or where) and they should be named so we know + // where and how they were created. E.g., WinOS-AES-ECB.dat, + // Sparc-Solaris-AEC-CBC-PKCS5Padding.dat, etc., but they should be + // able to be decrypted from any platform. May wish to place that + // under a separate JUnit test. + // + // TODO - Need to test rainy day paths of new encrypt / decrypt so can + // verify that exception handling working OK, etc. Maybe also in + // a separate JUnit test, since everything here seems to be sunny + // day path. (Note: Some of this no in new test case, + // org.owasp.esapi.crypto.ESAPICryptoMACByPassTest.) + // + // -kevin wall + + + /** + * Test of sign method, of class org.owasp.esapi.Encryptor. + * + * @throws EncryptionException + * the encryption exception + */ + public void testSign() throws EncryptionException { + System.out.println("testSign()"); + Encryptor instance = ESAPI.encryptor(); + String plaintext = ESAPI.randomizer().getRandomString( 32, EncoderConstants.CHAR_ALPHANUMERICS ); + String signature = instance.sign(plaintext); + assertTrue( instance.verifySignature( signature, plaintext ) ); + assertFalse( instance.verifySignature( signature, "ridiculous" ) ); + assertFalse( instance.verifySignature( "ridiculous", plaintext ) ); + } + + /** + * Test of verifySignature method, of class org.owasp.esapi.Encryptor. + * + * @throws EncryptionException + * the encryption exception + */ + public void testVerifySignature() throws EncryptionException { + System.out.println("testVerifySignature()"); + Encryptor instance = ESAPI.encryptor(); + String plaintext = ESAPI.randomizer().getRandomString( 32, EncoderConstants.CHAR_ALPHANUMERICS ); + String signature = instance.sign(plaintext); + assertTrue( instance.verifySignature( signature, plaintext ) ); + } + + + /** + * Test of seal method, of class org.owasp.esapi.Encryptor. + * + * @throws IntegrityException + */ + public void testSeal() throws IntegrityException { + System.out.println("testSeal()"); + Encryptor instance = ESAPI.encryptor(); + String plaintext = ESAPI.randomizer().getRandomString( 32, EncoderConstants.CHAR_ALPHANUMERICS ); + String seal = instance.seal( plaintext, instance.getTimeStamp() + 1000*60 ); + instance.verifySeal( seal ); + + int progressMark = 1; + boolean caughtExpectedEx = false; + try { + seal = instance.seal("", instance.getTimeStamp() + 1000*60); + progressMark++; + instance.verifySeal(seal); + progressMark++; + } catch(Exception e) { + fail("Failed empty string test: " + e + "; progress mark = " + progressMark); + } + try { + seal = instance.seal(null, instance.getTimeStamp() + 1000*60); + fail("Did not throw expected IllegalArgumentException"); + } catch(IllegalArgumentException e) { + caughtExpectedEx = true; + } catch(Exception e) { + fail("Failed null string test; did not get expected IllegalArgumentException: " + e); + } + assertTrue(caughtExpectedEx); + + try { + seal = instance.seal("test", 0); + progressMark++; + // instance.verifySeal(seal); + progressMark++; + } catch(Exception e) { + fail("Fail test with 0 timestamp: " + e + "; progress mark = " + progressMark); + } + try { + seal = instance.seal("test", -1); + progressMark++; + // instance.verifySeal(seal); + progressMark++; + } catch(Exception e) { + fail("Fail test with -1 timestamp: " + e + "; progress mark = " + progressMark); + } + } + + /** + * Test of verifySeal method, of class org.owasp.esapi.Encryptor. + * + * @throws EnterpriseSecurityException + */ + public void testVerifySeal() throws EnterpriseSecurityException { + final int NSEC = 5; + System.out.println("testVerifySeal()"); + Encryptor instance = ESAPI.encryptor(); + String plaintext = "ridiculous:with:delimiters"; // Should now work w/ : (issue #28) + String seal = instance.seal( plaintext, instance.getRelativeTimeStamp( 1000 * NSEC ) ); + try { + assertNotNull("Encryptor.seal() returned null", seal ); + assertTrue("Failed to verify seal", instance.verifySeal( seal ) ); + } catch ( Exception e ) { + fail(); + } + int progressMark = 1; + try { + // NOTE: I regrouped these all into a single try / catch since they + // all test the same thing. Hence if one fails, they all should. + // Also changed these tests so they no longer depend on the + // deprecated encrypt() methods. IMO, *all these multiple + // similar tests are not really required*, as they all are more + // or less testing the same thing. + // -kevin wall + // ================================================================ + // Try to validate some invalid seals. + // + // All these should return false and log a warning with an Exception stack + // trace caused by an EncryptionException indicating "Invalid seal". + assertFalse( instance.verifySeal( plaintext ) ); + progressMark++; + assertFalse( instance.verifySeal( instance.encrypt( new PlainText(plaintext) ).getBase64EncodedRawCipherText() ) ); + progressMark++; + assertFalse( instance.verifySeal( instance.encrypt( new PlainText(100 + ":" + plaintext) ).getBase64EncodedRawCipherText() ) ); + progressMark++; + assertFalse( instance.verifySeal( instance.encrypt( new PlainText(Long.MAX_VALUE + ":" + plaintext) ).getBase64EncodedRawCipherText() ) ); + progressMark++; + assertFalse( instance.verifySeal( instance.encrypt( new PlainText(Long.MAX_VALUE + ":random:" + plaintext) ).getBase64EncodedRawCipherText() ) ); + progressMark++; + assertFalse( instance.verifySeal( instance.encrypt( new PlainText(Long.MAX_VALUE + ":random:" + plaintext+ ":badsig") ).getBase64EncodedRawCipherText() ) ); + progressMark++; + assertFalse( instance.verifySeal( instance.encrypt( new PlainText(Long.MAX_VALUE + ":random:" + plaintext + ":"+ instance.sign( Long.MAX_VALUE + ":random:" + plaintext) ) ).getBase64EncodedRawCipherText() ) ); + progressMark++; + } catch ( Exception e ) { + // fail("Failed invalid seal test # " + progressMark + " to verify seal."); + System.err.println("Failed seal verification at step # " + progressMark); + System.err.println("Exception was: " + e); + e.printStackTrace(System.err); + } + + try { + Thread.sleep(1000 * (NSEC + 1) ); + // Seal now past expiration date. + assertFalse( instance.verifySeal( seal ) ); + } catch ( Exception e ) { + fail("Failed expired seal test. Seal should be expired."); + } + } + + + @SuppressWarnings("deprecation") + public void testEncryptionSerialization() throws EncryptionException { + String secretMsg = "Secret Message"; + ESAPI.securityConfiguration().setCipherTransformation("AES/CBC/PKCS5Padding"); + CipherText ct = ESAPI.encryptor().encrypt(new PlainText(secretMsg)); + + byte[] serializedCipherText = ct.asPortableSerializedByteArray(); + + PlainText plainText = ESAPI.encryptor().decrypt( + CipherText.fromPortableSerializedBytes(serializedCipherText) ); + + assertTrue( secretMsg.equals( plainText.toString() ) ); + } + + /** + * Test of main method, of class org.owasp.esapi.Encryptor. Must be done by + * visual inspection for now. (Needs improvement.) + * @throws Exception + */ + public void testMain() throws Exception { + System.out.println("testMain(): Encryptor Main with '-print' argument."); + String[] args = {}; + JavaEncryptor.main( args ); + // TODO: + // It probably would be a better if System.out were changed to be + // a file or a byte stream so that the output could be slurped up + // and checked against (at least some of) the expected output. + // Left as an exercise to some future, ambitious ESAPI developer. ;-) + String[] args1 = {"-print"}; + JavaEncryptor.main( args1 ); + } +} diff --git a/src/test/java/org/owasp/esapi/reference/crypto/ReferenceEncryptedPropertiesTest.java b/src/test/java/org/owasp/esapi/reference/crypto/ReferenceEncryptedPropertiesTest.java new file mode 100644 index 000000000..eaa2507b6 --- /dev/null +++ b/src/test/java/org/owasp/esapi/reference/crypto/ReferenceEncryptedPropertiesTest.java @@ -0,0 +1,499 @@ +/** + * 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.reference.crypto; + +import static org.junit.Assert.*; + +import java.io.*; +import java.util.Collection; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.Properties; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.owasp.esapi.errors.EncryptionException; +import org.owasp.esapi.errors.EncryptionRuntimeException; + +/** + * The Class EncryptedPropertiesTest. + * + * @author August Detlefsen (augustd at codemagi dot com) + * CodeMagi, Inc. + * @since October 8, 2010 + */ +public class ReferenceEncryptedPropertiesTest { + + @Rule + public TemporaryFolder tempFolder = new TemporaryFolder(); + + /** + * Test of getProperty method, of class org.owasp.esapi.EncryptedProperties. + * + * @throws EncryptionException + * the encryption exception + */ + @Test public void testGetProperty() throws EncryptionException { + System.out.println("getProperty"); + ReferenceEncryptedProperties instance = new ReferenceEncryptedProperties(); + String name = "name"; + String value = "value"; + instance.setProperty(name, value); + String result = instance.getProperty(name); + assertEquals(value, result); + assertNull(instance.getProperty("ridiculous")); + } + + /** + * Test of setProperty method, of class org.owasp.esapi.EncryptedProperties. + * + * @throws EncryptionException + * the encryption exception + */ + @Test public void testSetProperty() throws EncryptionException { + System.out.println("setProperty"); + ReferenceEncryptedProperties instance = new ReferenceEncryptedProperties(); + String name = "name"; + String value = "value"; + instance.setProperty(name, value); + String result = instance.getProperty(name); + assertEquals(value, result); + + instance.setProperty(name, ""); + result = instance.getProperty(name); + assertEquals(result, ""); + + try { + instance.setProperty(null, value); + fail("testSetProperty(): Null property name did not result in expected exception."); + } catch( Exception e ) { + assertTrue( e instanceof EncryptionRuntimeException ); + } + try { + instance.setProperty(name, null); + fail("testSetProperty(): Null property value did not result in expected exception."); + } catch( Exception e ) { + assertTrue( e instanceof EncryptionRuntimeException ); + } + try { + instance.setProperty(null, null); + fail("testSetProperty(): Null property name and valud did not result in expected exception."); + } catch( Exception e ) { + assertTrue( e instanceof EncryptionRuntimeException ); + } + } + + /** + * Test the behavior when the requested key does not exist. + */ + @Test public void testNonExistantKeyValue() throws Exception + { + ReferenceEncryptedProperties instance = new ReferenceEncryptedProperties(); + assertNull(instance.getProperty("not.there")); + } + + /** + * Test of keySet method, of class org.owasp.esapi.EncryptedProperties. + */ + @Test public void testKeySet() throws Exception + { + boolean sawTwo = false; + boolean sawOne = false; + + System.out.println("keySet"); + ReferenceEncryptedProperties instance = new ReferenceEncryptedProperties(); + instance.setProperty("one", "two"); + instance.setProperty("two", "three"); + Iterator i = instance.keySet().iterator(); + while(i.hasNext()) + { + String key = (String)i.next(); + + assertNotNull("key returned from keySet() iterator was null", key); + if(key.equals("one")) + if(sawOne) + fail("Key one seen more than once."); + else + sawOne = true; + else if(key.equals("two")) + if(sawTwo) + fail("Key two seen more than once."); + else + sawTwo = true; + else + fail("Unset key " + key + " returned from keySet().iterator()"); + } + assertTrue("Key one was never seen", sawOne); + assertTrue("Key two was never seen", sawTwo); + } + + /** + * Test storing and loading of encrypted properties. + */ + @Test public void testStoreLoad() throws Exception + { + ReferenceEncryptedProperties toLoad = new ReferenceEncryptedProperties(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ByteArrayInputStream bais; + boolean sawOne = false; + boolean sawTwo = false; + boolean sawSeuss = false; + + ReferenceEncryptedProperties toStore = new ReferenceEncryptedProperties(); + toStore.setProperty("one", "two"); + toStore.setProperty("two", "three"); + toStore.setProperty("seuss.schneier", "one fish, twofish, red fish, blowfish"); + toStore.store(baos, "testStore"); + + bais = new ByteArrayInputStream(baos.toByteArray()); + toLoad.load(bais); + + for(Iterator i=toLoad.keySet().iterator();i.hasNext();) + { + String key = (String)i.next(); + + assertNotNull("key returned from keySet() iterator was null", key); + if(key.equals("one")) + if(sawOne) + fail("Key one seen more than once."); + else + { + sawOne = true; + assertEquals("Key one's value was not two", "two", toLoad.getProperty("one")); + } + else if(key.equals("two")) + if(sawTwo) + fail("Key two seen more than once."); + else + { + sawTwo = true; + assertEquals("Key two's value was not three", "three", toLoad.getProperty("two")); + } + else if(key.equals("seuss.schneier")) + if(sawSeuss) + fail("Key seuss.schneier seen more than once."); + else + { + sawSeuss = true; + assertEquals("Key seuss.schneier's value was not expected value", + "one fish, twofish, red fish, blowfish", + toStore.getProperty("seuss.schneier")); + } + else + fail("Unset key " + key + " returned from keySet().iterator()"); + } + assertTrue("Key one was never seen", sawOne); + assertTrue("Key two was never seen", sawTwo); + } + + /** + * Test storing and loading of encrypted properties. + */ + @Test public void testStoreLoadWithReader() throws Exception + { +/* + //create an EncryptedProperties to store + ReferenceEncryptedProperties toStore = new ReferenceEncryptedProperties(); + toStore.setProperty("one", "two"); + toStore.setProperty("two", "three"); + toStore.setProperty("seuss.schneier", "one fish, twofish, red fish, blowfish"); + + //store properties to a Writer + CharArrayWriter writer = new CharArrayWriter(); + //toStore.store(writer, "testStore"); + + //read it back in from a Reader + Reader reader = new CharArrayReader(writer.toCharArray()); + + ReferenceEncryptedProperties toLoad = new ReferenceEncryptedProperties(); + toLoad.load(reader); + + //test the resulting loaded properties + boolean sawOne = false; + boolean sawTwo = false; + boolean sawSeuss = false; + + for(Iterator i=toLoad.keySet().iterator();i.hasNext();) + { + String key = (String)i.next(); + + assertNotNull("key returned from keySet() iterator was null", key); + if(key.equals("one")) + if(sawOne) + fail("Key one seen more than once."); + else + { + sawOne = true; + assertEquals("Key one's value was not two", "two", toLoad.getProperty("one")); + } + else if(key.equals("two")) + if(sawTwo) + fail("Key two seen more than once."); + else + { + sawTwo = true; + assertEquals("Key two's value was not three", "three", toLoad.getProperty("two")); + } + else if(key.equals("seuss.schneier")) + if(sawSeuss) + fail("Key seuss.schneier seen more than once."); + else + { + sawSeuss = true; + assertEquals("Key seuss.schneier's value was not expected value", + "one fish, twofish, red fish, blowfish", + toStore.getProperty("seuss.schneier")); + } + else + fail("Unset key " + key + " returned from keySet().iterator()"); + } + assertTrue("Key one was never seen", sawOne); + assertTrue("Key two was never seen", sawTwo); +*/ + } + + /** + * Test overridden put method. + */ + @Test public void testPut() throws Exception + { + ReferenceEncryptedProperties props = new ReferenceEncryptedProperties(); + + String name = "name"; + String value = "value"; + + props.put(name, value); //should work and store encrypted + String result = props.getProperty(name); + assertEquals(value, result); + + Integer five = new Integer(5); + + try { + props.put("Integer", five); //should fail and throw IllegalArgumentException + fail("testPut(): Non-String property value did not result in expected exception."); + } catch( Exception e ) { + assertTrue( e instanceof IllegalArgumentException ); + } + try { + props.put(five, "Integer"); //should fail and throw IllegalArgumentException + fail("testPut(): Non-String property key did not result in expected exception."); + } catch( Exception e ) { + assertTrue( e instanceof IllegalArgumentException ); + } + try { + props.put(five, five); //should fail and throw IllegalArgumentException + fail("testPut(): Non-String property key and value did not result in expected exception."); + } catch( Exception e ) { + assertTrue( e instanceof IllegalArgumentException ); + } + try { + props.put(null, five); + fail("testSetProperty(): Null property name and non-String value did not result in expected exception."); + } catch( Exception e ) { + assertTrue( e instanceof IllegalArgumentException ); + } + try { + props.put(five, null); + fail("testSetProperty(): Non-String key and null property value did not result in expected exception."); + } catch( Exception e ) { + assertTrue( e instanceof IllegalArgumentException ); + } + try { + props.put(null, value); + fail("testSetProperty(): Null property name did not result in expected exception."); + } catch( Exception e ) { + assertTrue( e instanceof IllegalArgumentException ); + } + try { + props.put(name, null); + fail("testSetProperty(): Null property value did not result in expected exception."); + } catch( Exception e ) { + assertTrue( e instanceof IllegalArgumentException ); + } + try { + props.put(null, null); + fail("testSetProperty(): Null property name and valud did not result in expected exception."); + } catch( Exception e ) { + assertTrue( e instanceof IllegalArgumentException ); + } + } + + /** + * Test that ReferenceEncryptedProperties can be properly constructed + * with an instance of Properties. + */ + @Test public void testConstructWithProperties() { + Properties props = new Properties(); + props.setProperty("one", "two"); + props.setProperty("two", "three"); + props.setProperty("seuss.schneier", "one fish, twofish, red fish, blowfish"); + + ReferenceEncryptedProperties eProps = new ReferenceEncryptedProperties(props); + + boolean sawOne = false; + boolean sawTwo = false; + boolean sawSeuss = false; + + for(Iterator i=eProps.keySet().iterator();i.hasNext();) + { + String key = (String)i.next(); + + assertNotNull("key returned from keySet() iterator was null", key); + if(key.equals("one")) + if(sawOne) + fail("Key one seen more than once."); + else + { + sawOne = true; + assertEquals("Key one's value was not two", "two", eProps.getProperty("one")); + } + else if(key.equals("two")) + if(sawTwo) + fail("Key two seen more than once."); + else + { + sawTwo = true; + assertEquals("Key two's value was not three", "three", eProps.getProperty("two")); + } + else if(key.equals("seuss.schneier")) + if(sawSeuss) + fail("Key seuss.schneier seen more than once."); + else + { + sawSeuss = true; + assertEquals("Key seuss.schneier's value was not expected value", + "one fish, twofish, red fish, blowfish", + eProps.getProperty("seuss.schneier")); + } + else + fail("Unset key " + key + " returned from keySet().iterator()"); + } + assertTrue("Key one was never seen", sawOne); + assertTrue("Key two was never seen", sawTwo); + } + + /** + * Test that ReferenceEncryptedProperties can be properly constructed + * with an instance of EncryptedProperties. + */ + @Test public void testConstructWithEncryptedProperties() throws Exception { + ReferenceEncryptedProperties props = new ReferenceEncryptedProperties(); + props.setProperty("one", "two"); + props.setProperty("two", "three"); + props.setProperty("seuss.schneier", "one fish, twofish, red fish, blowfish"); + + ReferenceEncryptedProperties eProps = new ReferenceEncryptedProperties(props); + + boolean sawOne = false; + boolean sawTwo = false; + boolean sawSeuss = false; + + for(Iterator i=eProps.keySet().iterator();i.hasNext();) + { + String key = (String)i.next(); + + assertNotNull("key returned from keySet() iterator was null", key); + if(key.equals("one")) + if(sawOne) + fail("Key one seen more than once."); + else + { + sawOne = true; + assertEquals("Key one's value was not two", "two", eProps.getProperty("one")); + } + else if(key.equals("two")) + if(sawTwo) + fail("Key two seen more than once."); + else + { + sawTwo = true; + assertEquals("Key two's value was not three", "three", eProps.getProperty("two")); + } + else if(key.equals("seuss.schneier")) + if(sawSeuss) + fail("Key seuss.schneier seen more than once."); + else + { + sawSeuss = true; + assertEquals("Key seuss.schneier's value was not expected value", + "one fish, twofish, red fish, blowfish", + eProps.getProperty("seuss.schneier")); + } + else + fail("Unset key " + key + " returned from keySet().iterator()"); + } + assertTrue("Key one was never seen", sawOne); + assertTrue("Key two was never seen", sawTwo); + } + + + /** + * Test overridden methods from Properties and Hashtable. + */ + @Test public void testOverriddenMethods() throws Exception { + Properties props = new ReferenceEncryptedProperties(); + props.setProperty("one", "two"); + props.setProperty("two", "three"); + props.setProperty("seuss.schneier", "one fish, twofish, red fish, blowfish"); + + FileOutputStream out = new FileOutputStream(tempFolder.newFile("ReferenceEncryptedProperties.test.txt")); + PrintStream ps = new PrintStream(out); + try { + props.list(ps); + fail("testOverriddenMethods(): list(PrintStream) did not result in expected Exception"); + } catch( Exception e ) { + assertTrue( e instanceof UnsupportedOperationException ); + } + + PrintWriter pw = new PrintWriter(new FileWriter(tempFolder.newFile("test.out"))); + try { + props.list(pw); + fail("testOverriddenMethods(): list(PrintWriter) did not result in expected Exception"); + } catch( Exception e ) { + assertTrue( e instanceof UnsupportedOperationException ); + } + + try { + props.list(ps); + fail("testOverriddenMethods(): list(PrintStream) did not result in expected Exception"); + } catch( Exception e ) { + assertTrue( e instanceof UnsupportedOperationException ); + } + + try { + Collection c = props.values(); + fail("testOverriddenMethods(): values() did not result in expected Exception"); + } catch( Exception e ) { + assertTrue( e instanceof UnsupportedOperationException ); + } + + try { + Collection c = props.entrySet(); + fail("testOverriddenMethods(): entrySet() did not result in expected Exception"); + } catch( Exception e ) { + assertTrue( e instanceof UnsupportedOperationException ); + } + + try { + Enumeration e = props.elements(); + fail("testOverriddenMethods(): elements() did not result in expected Exception"); + } catch( Exception e ) { + assertTrue( e instanceof UnsupportedOperationException ); + } + } + +} diff --git a/src/test/java/org/owasp/esapi/reference/regex/AbstractPatternTest.java b/src/test/java/org/owasp/esapi/reference/regex/AbstractPatternTest.java new file mode 100644 index 000000000..f887db57b --- /dev/null +++ b/src/test/java/org/owasp/esapi/reference/regex/AbstractPatternTest.java @@ -0,0 +1,70 @@ +/** + * 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-2018 - 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.reference.regex; + +import static org.junit.Assert.assertEquals; + +import java.util.regex.Pattern; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +/** + * Abstract parameterized test case meant to assist with verifying regular expressions in test scope. + *
+ * Sub-classes are expected to provide instances of {@link PatternTestTuple} to this instance. + *
+ * For better test naming output specify {@link PatternTestTuple#description} and use @Parameters (name="{0}"), + * where '0' is the index that the PatternTestTuple reference appears in the constructor. + */ +@RunWith(Parameterized.class) +public abstract class AbstractPatternTest { + + /** + * Test tuple for Pattern validation. + */ + protected static class PatternTestTuple { + /** String value to be tested against the compiled regex reference. */ + String input; + /** Regular expression string that will be compiled and be passed the input. */ + String regex; + /** Test Expectation whether input should match the compiled regex. */ + boolean shouldMatch; + /** Optional field to override the toString value of this tuple. */ + String description; + + /** {@inheritDoc} */ + @Override + public String toString() { + return description != null ? description : regex; + } + } + + private String input; + private Pattern pattern; + private boolean shouldMatch; + + public AbstractPatternTest(PatternTestTuple tuple) { + this.input = tuple.input; + this.pattern = Pattern.compile(tuple.regex); + this.shouldMatch = tuple.shouldMatch; + } + + @Test + public void checkPatternMatches() { + assertEquals(shouldMatch, pattern.matcher(input).matches()); + } + +} diff --git a/src/test/java/org/owasp/esapi/reference/regex/EsapiWhitelistValidationPatternTester.java b/src/test/java/org/owasp/esapi/reference/regex/EsapiWhitelistValidationPatternTester.java new file mode 100644 index 000000000..b6080344d --- /dev/null +++ b/src/test/java/org/owasp/esapi/reference/regex/EsapiWhitelistValidationPatternTester.java @@ -0,0 +1,103 @@ +/** + * 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-2018 - 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.reference.regex; + +import java.util.ArrayList; +import java.util.Collection; + +import org.junit.Assume; +import org.junit.runners.Parameterized.Parameters; +import org.owasp.esapi.reference.DefaultSecurityConfiguration; + +/** + * Extension of the AbstractPatternTest which focuses on asserting that the default whitelist regex values applied in + * the validation process are performing the intended function in the environment. + *
+ * If the regex values in this test are found to not match the running environment configurations, then the tests will + * be skipped. + * + * @author Jeremiah + * @since Jan 20, 2018 + */ +public class EsapiWhitelistValidationPatternTester extends AbstractPatternTest { + // See ESAPI.properties + private static final String HTTP_QUERY_STRING_PROP_NAME = "HTTPQueryString"; + private static final String HTTP_QUERY_STRING_REGEX = "^([a-zA-Z0-9_\\-]{1,32}=[\\p{L}\\p{N}.\\-/+=_ !$*?@%]*&?)*$"; + + private static final String CONFIGURATION_PATTERN_MISMATCH_MESSAGE = "The regular expression specified does not match the configuration settings.\n" + + "If the value was changed from the ESAPI default, it is recommended to copy " + + "this class into your project, update the regex being tested, and update all " + + "associated input expectations for your unique environment."; + + @Parameters(name = "{0}-{1}") + public static Collection createDefaultPatternTests() { + Collection parameters = new ArrayList<>(); + + for (PatternTestTuple tuple : buildHttpQueryStringTests()) { + parameters.add(new Object[] { HTTP_QUERY_STRING_PROP_NAME, tuple }); + } + + return parameters; + } + + private static Collection buildHttpQueryStringTests() { + Collection httpQueryStringTests = new ArrayList<>(); + + // MATCHING CASES + PatternTestTuple tuple = newHttpQueryStringTuple("Default Case", "b", true); + httpQueryStringTests.add(tuple); + tuple = newHttpQueryStringTuple("Percent Encoded Value", "%62", true); + httpQueryStringTests.add(tuple); + tuple = newHttpQueryStringTuple("Percent Encoded Null Character", "%00", true); + httpQueryStringTests.add(tuple); + tuple = newHttpQueryStringTuple("Double Equals", "=", true); + httpQueryStringTests.add(tuple); + + // NON-MATCHING CASES + tuple = newHttpQueryStringTuple("Ampersand In Value", "&b", false); + httpQueryStringTests.add(tuple); + tuple = newHttpQueryStringTuple("Null Character", "" + Character.MIN_VALUE, false); + httpQueryStringTests.add(tuple); + tuple = newHttpQueryStringTuple("Encoded Null Character", "\u0000", false); + httpQueryStringTests.add(tuple); + + return httpQueryStringTests; + } + + private static PatternTestTuple newHttpQueryStringTuple(String description, String value, boolean shouldPass) { + PatternTestTuple tuple = new PatternTestTuple(); + tuple.input = "a=" + value; + tuple.shouldMatch = shouldPass; + tuple.regex = HTTP_QUERY_STRING_REGEX; + tuple.description = description; + return tuple; + } + + public EsapiWhitelistValidationPatternTester(String property, PatternTestTuple tuple) { + super(tuple); + /* + * This next block causes the case to be skipped programatically if the regex being tested + * is different than the one being loaded at runtime. + * This is being done to prevent a false sense of security. + * If the configurations are changed to meet additional environmental concerns, the intent of this test should + * be copied into that environment and tested there to assert the additional expectations or changes in desired + * behavior. + */ + DefaultSecurityConfiguration configuration = new DefaultSecurityConfiguration(); + Assume.assumeTrue(CONFIGURATION_PATTERN_MISMATCH_MESSAGE, configuration.getValidationPattern(property) + .toString().equals(tuple.regex)); + } + +} diff --git a/src/test/java/org/owasp/esapi/reference/validation/BaseValidationRuleTest.java b/src/test/java/org/owasp/esapi/reference/validation/BaseValidationRuleTest.java new file mode 100644 index 000000000..36a7b1b99 --- /dev/null +++ b/src/test/java/org/owasp/esapi/reference/validation/BaseValidationRuleTest.java @@ -0,0 +1,295 @@ +/** + * 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 Ben Sleek Sparta Systems + * @created 2015 + */ +package org.owasp.esapi.reference.validation; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.CALLS_REAL_METHODS; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.withSettings; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.hamcrest.Matcher; +import org.hamcrest.core.Is; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.owasp.esapi.Encoder; +import org.owasp.esapi.ValidationErrorList; +import org.owasp.esapi.errors.ValidationException; + +public class BaseValidationRuleTest { + /**Static Test Data.*/ + private static final String STR_VAL=""; + private static final String EX_MSG="Expected Failure Message from " + BaseValidationRuleTest.class.getSimpleName(); + @Rule + public ExpectedException exEx = ExpectedException.none(); + + private ValidationException testValidationEx = new ValidationException(EX_MSG, EX_MSG); + + private BaseValidationRule uit = mock(BaseValidationRule.class, CALLS_REAL_METHODS); + @Test + public void testCtrNullTypeName() throws Exception { + String typename = null; + BaseValidationRule rule = mock(BaseValidationRule.class, withSettings() + .useConstructor(typename) + .defaultAnswer(CALLS_REAL_METHODS) + ); + assertNull(rule.getTypeName()); + } + + @Test + public void testCtrNullEncoder() { + String typename = "typename"; + Encoder encoder = null; + BaseValidationRule rule = mock(BaseValidationRule.class, withSettings() + .useConstructor(typename, encoder) + .defaultAnswer(CALLS_REAL_METHODS) + ); + assertEquals(typename, rule.getTypeName()); + assertNull(rule.getEncoder()); + } + + @Test + public void testCtrNullTypenameNullEncoder() { + String typename = null; + Encoder encoder = null; + BaseValidationRule rule = mock(BaseValidationRule.class, withSettings() + .useConstructor(typename, encoder) + .defaultAnswer(CALLS_REAL_METHODS) + ); + assertNull(rule.getTypeName()); + assertNull(rule.getEncoder()); + } + + @Test + public void testCtr2ArgHappyPath() { + String typename = "typename"; + Encoder encoder = mock(Encoder.class); + BaseValidationRule rule = mock(BaseValidationRule.class, withSettings() + .useConstructor(typename, encoder) + .defaultAnswer(CALLS_REAL_METHODS) + ); + assertEquals(typename, rule.getTypeName()); + assertEquals(encoder, rule.getEncoder()); + } + + @Test + public void testCtr1ArgHappyPath() { + String typename = "typename"; + mock(BaseValidationRule.class, withSettings() + .useConstructor(typename) + .defaultAnswer(CALLS_REAL_METHODS) + ); + } + + @Test + public void testSetTypeNameNull() { + uit.setTypeName(null); + assertNull(uit.getTypeName()); + } + + @Test + public void testSetTypeName() { + uit.setTypeName(STR_VAL); + assertEquals(STR_VAL, uit.getTypeName()); + } + + @Test + public void testSetEncoderNull() { + uit.setEncoder(null); + assertNull(uit.getEncoder()); + } + + @Test + public void testSetEncoder() { + Encoder mockEnc = mock(Encoder.class); + uit.setEncoder(mockEnc); + assertEquals(mockEnc, uit.getEncoder()); + } + + @Test + public void testSetAllowNull() { + uit.setAllowNull(true); + assertTrue(uit.isAllowNull()); + uit.setAllowNull(false); + assertFalse(uit.isAllowNull()); + } + + @Test + public void testAssertValidCallsGetValid() throws ValidationException { + when(uit.getValid(STR_VAL, STR_VAL)).thenReturn(this); + uit.assertValid(STR_VAL, STR_VAL); + verify(uit, times(1)).getValid(STR_VAL, STR_VAL); + } + @Test + public void testAssertValidThrowsValidationException() throws ValidationException { + /* + * Verifies assertValid throws ValidationException on invalid input + * Validates fix for Google issue #195 + */ + Matcher validationExMatch = Is.is(testValidationEx); + exEx.expect(validationExMatch); + when(uit.getValid(STR_VAL, STR_VAL)).thenThrow(testValidationEx); + uit.assertValid(STR_VAL, STR_VAL); + } + + @Test + public void testGetValidErrorListCallsGetValid() throws ValidationException { + ValidationErrorList vel = new ValidationErrorList(); + when(uit.getValid(STR_VAL, STR_VAL)).thenReturn(this); + Object vRef = uit.getValid(STR_VAL, STR_VAL, vel); + assertEquals(this, vRef); + verify(uit, times(1)).getValid(STR_VAL, STR_VAL); + } + + @Test + public void testGetValidExceptionAddedToErrorList() throws ValidationException { + ValidationErrorList vel = new ValidationErrorList(); + when(uit.getValid(STR_VAL, STR_VAL)).thenThrow(testValidationEx); + Object vRef = uit.getValid(STR_VAL, STR_VAL, vel); + assertNull(vRef); + List elEx = vel.errors(); + assertEquals(1, elEx.size()); + assertEquals(testValidationEx, elEx.get(0)); + verify(uit, times(1)).getValid(STR_VAL, STR_VAL); + } + @Test + public void testGetValidNullErrorListThrows() throws ValidationException { + Matcher validationExMatch = Is.is(testValidationEx); + exEx.expect(validationExMatch); + ValidationErrorList vel = null; + when(uit.getValid(STR_VAL, STR_VAL)).thenThrow(testValidationEx); + uit.getValid(STR_VAL, STR_VAL, vel); + } + + @Test + public void testGetSafeCallsGetValid() throws ValidationException { + when(uit.getValid(STR_VAL, STR_VAL)).thenReturn(this); + Object vRef = uit.getSafe(STR_VAL, STR_VAL); + assertEquals(this, vRef); + verify(uit, times(1)).getValid(STR_VAL, STR_VAL); + } + + @Test + public void testGetSafeOnExceptionCallsSanitize() throws ValidationException { + when(uit.getValid(STR_VAL, STR_VAL)).thenThrow(testValidationEx); + when(uit.sanitize(STR_VAL, STR_VAL)).thenReturn(this); + Object vRef = uit.getSafe(STR_VAL, STR_VAL); + assertEquals(this, vRef); + verify(uit, times(1)).getValid(STR_VAL, STR_VAL); + verify(uit, times(1)).sanitize(STR_VAL, STR_VAL); + } + + @Test + public void testIsValidCallsGetValid() throws ValidationException { + when(uit.getValid(STR_VAL, STR_VAL)).thenReturn(this); + assertTrue(uit.isValid(STR_VAL, STR_VAL)); + verify(uit, times(1)).getValid(STR_VAL, STR_VAL); + } + + @Test + public void testIsValidOnExceptionRetursFalse() throws ValidationException { + when(uit.getValid(STR_VAL, STR_VAL)).thenThrow(testValidationEx); + assertFalse(uit.isValid(STR_VAL, STR_VAL)); + verify(uit, times(1)).getValid(STR_VAL, STR_VAL); + } + + /* ************************* + * TO DISCUSS + * FIXME + * Tests below this block are items which are valid against the current implementation, but have side effects + * or unclear results under certain conditions. + * + * Once Items are discussed and understood they should probably be well-commented and moved out of this area. + */ + + @Test + public void testGetValidMultipleExceptionSameContextThrowsRuntimeException() throws ValidationException { + exEx.expect(RuntimeException.class); + ValidationErrorList vel = new ValidationErrorList(); + when(uit.getValid(STR_VAL, STR_VAL)).thenThrow(testValidationEx); + uit.getValid(STR_VAL, STR_VAL, vel); + /* + * Side-effect of ValidationErrorList. If the same context is used against a BaseValidationRule multiple times resulting in exception, the ValidationErrorList impl will blow up. + * This can be an unclear event at runtime if a single BaseValidationRule instance is shared in an application and multiple parts happen to use the same contextual string to capture failure events. + * + */ + uit.getValid(STR_VAL, STR_VAL, vel); + } + + //None of the Whitelist content belongs in this class, IMO. + + @Test + public void testWhitelistCharArrayCleansString() { + String myString = "AAAGaaadBBB12345*"; + char[] whitelist = new char[] {'d', 'G', '3', '*', ']'}; + String result = uit.whitelist(myString, whitelist); + assertEquals("Gd3*", result); + } + + @Test + public void testWhitelistNullCharArrayThrows() { + exEx.expect(NullPointerException.class); + String myString = "AAAGaaadBBB12345*"; + char[] whitelist = null; + uit.whitelist(myString, whitelist); + } + + @Test + public void testWhitelistSetCleansString() { + String myString = "AAAGaaadBBB12345*"; + Set whitelist = new HashSet<>(); + whitelist.add('d'); + whitelist.add('G'); + whitelist.add('3'); + whitelist.add('*'); + whitelist.add(']'); + String result = uit.whitelist(myString, whitelist); + assertEquals("Gd3*", result); + } + + @Test + public void testWhitelistNullSetThrows() { + exEx.expect(NullPointerException.class); + String myString = "AAAGaaadBBB12345*"; + Set whitelist = null; + uit.whitelist(myString, whitelist); + } + + @Test + + public void testWhitelistSetExtendedCharacterSets() { + String myString = "đˇľđ¦´©<𥻂"; + //(55365 56894) (55387 56617) 60 (55383 57026) + Set whitelist = new HashSet<>(); + whitelist.add((char) 60); + whitelist.add((char) 55387); + whitelist.add((char) 56617); + String result = uit.whitelist(myString, whitelist); + assertEquals("𦴩<", result); + } +} diff --git a/src/test/java/org/owasp/esapi/reference/validation/DateValidationRulePowerMockTest.java b/src/test/java/org/owasp/esapi/reference/validation/DateValidationRulePowerMockTest.java new file mode 100644 index 000000000..1b7c9ed82 --- /dev/null +++ b/src/test/java/org/owasp/esapi/reference/validation/DateValidationRulePowerMockTest.java @@ -0,0 +1,141 @@ +package org.owasp.esapi.reference.validation; + +import java.text.DateFormat; +import java.util.Locale; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestName; +import org.junit.runner.RunWith; +import org.mockito.ArgumentMatchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.internal.verification.VerificationModeFactory; +import org.owasp.esapi.Encoder; +import org.owasp.esapi.SecurityConfiguration; +import org.owasp.esapi.util.ObjFactory; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ObjFactory.class}) +public class DateValidationRulePowerMockTest { + + @Rule + public TestName testName = new TestName(); + private Encoder mockEncoder; + private DateFormat testFormat = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.US); + private DateValidationRule uit; + @Mock + private SecurityConfiguration mockSecConfig; + + @Before + public void configureStaticContexts() throws Exception { + PowerMockito.mockStatic(ObjFactory.class); + PowerMockito.when(ObjFactory.class, "make", ArgumentMatchers.anyString(), ArgumentMatchers.eq("SecurityConfiguration")).thenReturn(mockSecConfig); + + mockEncoder = Mockito.mock(Encoder.class); + testFormat = Mockito.spy(testFormat); + } + + @Test + public void testSetDateFormatLenientTrueFromCtr() { + Mockito.when(mockSecConfig.getLenientDatesAccepted()).thenReturn(true); + + testFormat.setLenient(false); + Mockito.reset(testFormat); + + uit = new DateValidationRule(testName.getMethodName(), mockEncoder, testFormat); + + Assert.assertTrue(testFormat.isLenient()); + + Mockito.verify(mockSecConfig, Mockito.times(1)).getLenientDatesAccepted(); + Mockito.verify(testFormat, Mockito.times(1)).setLenient(true); + Mockito.verify(testFormat, Mockito.times(0)).setLenient(false); + + PowerMockito.verifyStatic(ObjFactory.class, VerificationModeFactory.times(1)); + ObjFactory.make(ArgumentMatchers.anyString(), ArgumentMatchers.eq("SecurityConfiguration")); + + PowerMockito.verifyNoMoreInteractions(ObjFactory.class); + + + } + + @Test + public void testSetDateFormatLenientFalseFromCtr() { + Mockito.when(mockSecConfig.getLenientDatesAccepted()).thenReturn(false); + + testFormat.setLenient(true); + Mockito.reset(testFormat); + + uit = new DateValidationRule(testName.getMethodName(), mockEncoder, testFormat); + + Assert.assertFalse(testFormat.isLenient()); + + Mockito.verify(mockSecConfig, Mockito.times(1)).getLenientDatesAccepted(); + Mockito.verify(testFormat, Mockito.times(0)).setLenient(true); + Mockito.verify(testFormat, Mockito.times(1)).setLenient(false); + + PowerMockito.verifyStatic(ObjFactory.class, VerificationModeFactory.times(1)); + ObjFactory.make(ArgumentMatchers.anyString(), ArgumentMatchers.eq("SecurityConfiguration")); + + PowerMockito.verifyNoMoreInteractions(ObjFactory.class); + } + + @Test + public void testSetDateFormatLenientFalseFromSetter() { + Mockito.when(mockSecConfig.getLenientDatesAccepted()).thenReturn(false); + + uit = new DateValidationRule(testName.getMethodName(), mockEncoder, testFormat); + + //Configuration is lenient=false + testFormat.setLenient(true); + Mockito.reset(testFormat, mockSecConfig); + Assert.assertTrue(testFormat.isLenient()); + + Mockito.when(mockSecConfig.getLenientDatesAccepted()).thenReturn(false); + + uit.setDateFormat(testFormat); + + Assert.assertFalse(testFormat.isLenient()); + + Mockito.verify(mockSecConfig, Mockito.times(1)).getLenientDatesAccepted(); + Mockito.verify(testFormat, Mockito.times(0)).setLenient(true); + Mockito.verify(testFormat, Mockito.times(1)).setLenient(false); + + PowerMockito.verifyStatic(ObjFactory.class, VerificationModeFactory.times(2)); + ObjFactory.make(ArgumentMatchers.anyString(), ArgumentMatchers.eq("SecurityConfiguration")); + + PowerMockito.verifyNoMoreInteractions(ObjFactory.class); + } + + @Test + public void testSetDateFormatLenientTrueFromSetter() { + Mockito.when(mockSecConfig.getLenientDatesAccepted()).thenReturn(true); + + uit = new DateValidationRule(testName.getMethodName(), mockEncoder, testFormat); + + //Configuration is lenient=true + testFormat.setLenient(false); + Mockito.reset(testFormat, mockSecConfig); + Assert.assertFalse(testFormat.isLenient()); + + Mockito.when(mockSecConfig.getLenientDatesAccepted()).thenReturn(true); + + uit.setDateFormat(testFormat); + + Assert.assertTrue(testFormat.isLenient()); + + Mockito.verify(mockSecConfig, Mockito.times(1)).getLenientDatesAccepted(); + Mockito.verify(testFormat, Mockito.times(1)).setLenient(true); + Mockito.verify(testFormat, Mockito.times(0)).setLenient(false); + + PowerMockito.verifyStatic(ObjFactory.class, VerificationModeFactory.times(2)); + ObjFactory.make(ArgumentMatchers.anyString(), ArgumentMatchers.eq("SecurityConfiguration")); + + PowerMockito.verifyNoMoreInteractions(ObjFactory.class); + } +} diff --git a/src/test/java/org/owasp/esapi/reference/validation/DateValidationRuleTest.java b/src/test/java/org/owasp/esapi/reference/validation/DateValidationRuleTest.java new file mode 100644 index 000000000..57e9d021e --- /dev/null +++ b/src/test/java/org/owasp/esapi/reference/validation/DateValidationRuleTest.java @@ -0,0 +1,248 @@ +package org.owasp.esapi.reference.validation; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.Map.Entry; + +import org.hamcrest.CustomMatcher; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.TestName; +import org.mockito.ArgumentMatchers; +import org.mockito.Mockito; +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.Encoder; +import org.owasp.esapi.ValidationErrorList; +import org.owasp.esapi.errors.ValidationException; +import org.owasp.esapi.reference.DefaultSecurityConfiguration; +import static org.owasp.esapi.PropNames.ACCEPT_LENIENT_DATES; +import org.powermock.reflect.Whitebox; + +public class DateValidationRuleTest { + + @Rule + public ExpectedException exEx = ExpectedException.none(); + @Rule + public TestName testName = new TestName(); + private ParseException testParseEx = new ParseException("Test Exception", 0); + private Date testDate = new Date(); + private String dateString; + private String canonDateString ; + + private String contextStr; + private Encoder mockEncoder; + private DateFormat testFormat = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.US); + private DateValidationRule uit; + + @Before + public void setup() { + mockEncoder = Mockito.mock(Encoder.class); + testFormat = Mockito.spy(testFormat); + uit = new DateValidationRule(testName.getMethodName(), mockEncoder, testFormat); + contextStr = testName.getMethodName(); + + dateString = testFormat.format(testDate); + canonDateString = dateString; + } + @Test + public void testCtrNullDateFormatThrows() { + exEx.expect(IllegalArgumentException.class); + exEx.expectMessage("DateValidationRule.setDateFormat requires a non-null DateFormat"); + new DateValidationRule("context", mockEncoder, null); + } + + @Test + public void testCtrSetDateFormat() { + DateFormat uitFormat = Whitebox.getInternalState(uit, "format"); + Assert.assertEquals(testFormat, uitFormat); + } + + @Test + public void testsetDateFormatNullThrows() { + exEx.expect(IllegalArgumentException.class); + exEx.expectMessage("DateValidationRule.setDateFormat requires a non-null DateFormat"); + uit.setDateFormat(null); + } + + @Test + public void testsetDateFormat() { + boolean acceptLenient = ESAPI.securityConfiguration().getBooleanProp( ACCEPT_LENIENT_DATES ); + DateFormat newFormat = DateFormat.getDateInstance(DateFormat.SHORT, Locale.US); + newFormat.setLenient(!acceptLenient); + + newFormat = Mockito.spy(newFormat); + + uit.setDateFormat(newFormat); + DateFormat uitFormat = Whitebox.getInternalState(uit, "format"); + Assert.assertEquals(newFormat, uitFormat); + Mockito.verify(newFormat).setLenient(acceptLenient); + } + + @Test + public void testGetValidNullInputAllowed() throws ValidationException { + uit.setAllowNull(true); + Date vDate = uit.getValid(contextStr, null); + Assert.assertNull(vDate); + } + + @Test + public void testGetValidNullInputNotAllowed() throws ValidationException { + exEx.expect(ValidationException.class); + exEx.expectMessage("Input date required"); + uit.setAllowNull(false); + uit.getValid(contextStr, null); + } + + @Test + public void testGetValidNullInputNotAllowedEmptyString() throws ValidationException { + exEx.expect(ValidationException.class); + exEx.expectMessage("Input date required"); + uit.setAllowNull(false); + uit.getValid(contextStr, ""); + } + + @Test + public void testGetValidBadDateThrows() throws ValidationException, ParseException { + exEx.expect(ValidationException.class); + exEx.expectMessage(contextStr + ": Invalid date"); + exEx.expectCause(new CustomMatcher("Check for Test Parse Exception") { + + @Override + public boolean matches(Object item) { + return item.equals(testParseEx); + } + }); + + Mockito.when(mockEncoder.canonicalize(dateString)).thenReturn(canonDateString); + Mockito.doThrow(testParseEx).when(testFormat).parse(canonDateString); + + uit.getValid(contextStr, dateString); + } + + @Test + public void testGetValidHappyPath() throws ValidationException, ParseException { + Mockito.when(mockEncoder.canonicalize(dateString)).thenReturn(canonDateString); + Mockito.doReturn(testDate).when(testFormat).parse(canonDateString); + + Date date = uit.getValid(contextStr, dateString); + Assert.assertEquals(testDate, date); + } + + @Test + public void testGetValidDateWithCruft() throws ValidationException, ParseException { + String cruftyDate = canonDateString + "' union select * from another_table where user_id like '%"; + Mockito.when(mockEncoder.canonicalize(cruftyDate)).thenReturn(cruftyDate); + Mockito.doReturn(testDate).when(testFormat).parse(cruftyDate); + + Date date = uit.getValid(contextStr, cruftyDate); + Assert.assertEquals(testDate, date); + } + + + @Test + public void testSanitizeNullInputAllowed() throws ValidationException { + uit.setAllowNull(true); + Date vDate = uit.sanitize(contextStr, null); + Assert.assertNull(vDate); + } + + @Test + public void testSanitizeNullInputNotAllowed() throws ValidationException { + uit.setAllowNull(false); + Date date = uit.sanitize(contextStr, null); + Assert.assertEquals(0, date.getTime()); + } + + @Test + public void testSanitizeNullInputNotAllowedEmptyString() throws ValidationException { + uit.setAllowNull(false); + Date date = uit.sanitize(contextStr, ""); + Assert.assertEquals(0, date.getTime()); + } + + @Test + public void testSanitizeBadDateReturnsDefault() throws ValidationException, ParseException { + Mockito.when(mockEncoder.canonicalize(dateString)).thenReturn(canonDateString); + Mockito.doThrow(testParseEx).when(testFormat).parse(canonDateString); + + Date date = uit.sanitize(contextStr, dateString); + Assert.assertEquals(0, date.getTime()); + } + + @Test + public void testSanitizeErrorListContainsError() throws ValidationException, ParseException { + ValidationErrorList vel = new ValidationErrorList(); + Mockito.when(mockEncoder.canonicalize(dateString)).thenReturn(canonDateString); + Mockito.doThrow(testParseEx).when(testFormat).parse(canonDateString); + + Date date = uit.sanitize(contextStr, dateString, vel); + Assert.assertEquals(0, date.getTime()); + Assert.assertEquals(1, vel.size()); + ValidationException wrapper = vel.errors().get(0); + Assert.assertEquals(testParseEx, wrapper.getCause()); + } + + @Test + public void testSanitizeHappyPath() throws ValidationException, ParseException { + Mockito.when(mockEncoder.canonicalize(dateString)).thenReturn(canonDateString); + Mockito.doReturn(testDate).when(testFormat).parse(canonDateString); + + Date date = uit.sanitize(contextStr, dateString); + Assert.assertEquals(testDate, date); + } + @Test + public void testSanitizeDateWithCruft() throws ValidationException, ParseException { + String cruftyDate = canonDateString + "' union select * from another_table where user_id like '%"; + Mockito.when(mockEncoder.canonicalize(cruftyDate)).thenReturn(cruftyDate); + Mockito.doReturn(testDate).when(testFormat).parse(cruftyDate); + + Date date = uit.sanitize(contextStr, cruftyDate); + Assert.assertEquals(0, date.getTime()); + } + + @Test + public void testGithubIssue299() throws ParseException, ValidationException { + Map formatDateMap = new HashMap<>(); + formatDateMap.put(new SimpleDateFormat("dd/MM/yyyy"), "01/01/2aaa"); + formatDateMap.put(new SimpleDateFormat("yyyy/dd/MM"), "2aaa/01/01"); + formatDateMap.put(new SimpleDateFormat("dd/yyyy/MM"), "01/2012'SELECT * FROM user_table'/01"); + formatDateMap.put(new SimpleDateFormat("dd/MM/yyyy"),"01/01/2012'SELECT * FROM user_table'"); + formatDateMap.put(new SimpleDateFormat("dd/yyyy/MM"),"01/2aaa/01"); + formatDateMap.put(SimpleDateFormat.getDateInstance(SimpleDateFormat.LONG, Locale.US), "September 11, 2001' union select * from another_table where user_id like '%"); + + for (Entry pair : formatDateMap.entrySet()) { + String cruftyDate = pair.getValue(); + Mockito.when(mockEncoder.canonicalize(cruftyDate)).thenReturn(cruftyDate); + + DateFormat lenientFormat = Mockito.spy(pair.getKey()); + lenientFormat.setLenient(true); + Mockito.doNothing().when(lenientFormat).setLenient(ArgumentMatchers.anyBoolean()); + Mockito.doReturn(testDate).when(lenientFormat).parse(cruftyDate); + + DateFormat strictFormat = Mockito.spy(pair.getKey()); + strictFormat.setLenient(false); + Mockito.doNothing().when(strictFormat).setLenient(ArgumentMatchers.anyBoolean()); + Mockito.doReturn(testDate).when(strictFormat).parse(cruftyDate); + + uit.setDateFormat(lenientFormat); + Date lenientValidDate = uit.getValid(contextStr, cruftyDate); + Assert.assertEquals("calls to getValid should not change the parsed date regardless of cruft",testDate, lenientValidDate); + Date lenientSanitizedDate = uit.sanitize(contextStr, cruftyDate); + Assert.assertEquals("calls to sanitize should return default date if cruft exists in input string",0, lenientSanitizedDate.getTime()); + + uit.setDateFormat(strictFormat); + Date strictValidDate = uit.getValid(contextStr, cruftyDate); + Assert.assertEquals("calls to getValid should not change the parsed date regardless of cruft",testDate, strictValidDate); + Date strictSanitizedDate = uit.sanitize(contextStr, cruftyDate); + Assert.assertEquals("calls to sanitize should return default date if cruft exists in input string",0, strictSanitizedDate.getTime()); + } + } +} diff --git a/src/test/java/org/owasp/esapi/reference/validation/HTMLValidationRuleAntisamyPropertyTest.java b/src/test/java/org/owasp/esapi/reference/validation/HTMLValidationRuleAntisamyPropertyTest.java new file mode 100644 index 000000000..082bd626c --- /dev/null +++ b/src/test/java/org/owasp/esapi/reference/validation/HTMLValidationRuleAntisamyPropertyTest.java @@ -0,0 +1,36 @@ +/** + * 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) 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 kevin.w.wall@gmail.com + * @since 2019 + */ +package org.owasp.esapi.reference.validation; + +import org.junit.Test; +import org.owasp.validator.html.PolicyException; + +/** + * Isolate scope test to assert the behavior of the HTMLValidationRule + * when schema validation is disabled in the Antisamy Project. + */ +public class HTMLValidationRuleAntisamyPropertyTest { + /** The intentionally non-compliant AntiSamy policy file. We don't intend to + * actually use it for anything. + */ + private static final String INVALID_ANTISAMY_POLICY_FILE = "antisamy-InvalidPolicy.xml"; + + @Test( expected = PolicyException.class ) + public void checkAntisamySystemPropertyWorksAsAdvertised() throws Exception { + HTMLValidationRule.loadAntisamyPolicy(INVALID_ANTISAMY_POLICY_FILE); + } + +} diff --git a/src/test/java/org/owasp/esapi/reference/validation/HTMLValidationRuleClasspathTest.java b/src/test/java/org/owasp/esapi/reference/validation/HTMLValidationRuleClasspathTest.java new file mode 100644 index 000000000..9492c6b7c --- /dev/null +++ b/src/test/java/org/owasp/esapi/reference/validation/HTMLValidationRuleClasspathTest.java @@ -0,0 +1,175 @@ +/** + * 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) 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 kevin.w.wall@gmail.com + * @since 2019 + */ +package org.owasp.esapi.reference.validation; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.SecurityConfiguration; +import org.owasp.esapi.SecurityConfigurationWrapper; +import org.owasp.esapi.ValidationErrorList; +import org.owasp.esapi.Validator; +import org.owasp.esapi.errors.ValidationException; +import org.owasp.validator.html.PolicyException; +import static org.owasp.esapi.PropNames.VALIDATOR_HTML_VALIDATION_ACTION; +import static org.owasp.esapi.PropNames.VALIDATOR_HTML_VALIDATION_CONFIGURATION_FILE; + +/** + * The class {@code HTMLValidationRuleClasspathTest} is used to test ESAPI where + * the AntiSamy policy file is located in a non-standard place. It is based + * on te original test cases, testGetValidSafeHTML() and + * testIsValidSafeHTML() from the file {@code ValidatorTest} originally written + * by + * Mike Fauzy (mike.fauzy@aspectsecurity.com) and + * Jeff Williams (jeff.williams@aspectsecurity.com) + * that were originally part of "src/test/java/org/owasp/esapi/reference/ValidatorTest.java". + * + * This class tests the case of a non-standard AntiSamy policy file along with + * the case where the new ESAPI.property + * Validator.HtmlValidationAction + * is set to "throw", which causes certain calls to + * {@code ESAPI.validator().getValidSafeHTML()} + * to throw a ValidationException rather than simply logging a warning and returning + * the cleansed (sanitizied) output when certain unsafe input is encountered. + */ +public class HTMLValidationRuleClasspathTest { + /** The intentionally non-compliant (to the AntiSamy XSD) AntiSamy policy file. We don't intend to + * actually use it for anything other than to test that we report + * non-compliant AntiSamy policy files in a sane manner. + */ + private static final String INVALID_ANTISAMY_POLICY_FILE = "antisamy-InvalidPolicy.xml"; + + /** A compliant AntiSamy policy file that is just located in a non-standard + * place. We don't intend to * actually use it for anything other + * than testing. Otherwise, it's mostly identical to the AntiSamy policy + * file "src/test/resources/esapi/antisamy-esapi.xml". + */ + private static final String ANTISAMY_POLICY_FILE_NONSTANDARD_LOCATION = "antisamy-esapi-CP.xml"; + + private static class ConfOverride extends SecurityConfigurationWrapper { + private String desiredReturnAction = "clean"; + private String desiredReturnConfigurationFile = null; + + ConfOverride(SecurityConfiguration orig, String desiredReturnAction, String desiredReturnConfigurationFile) { + super(orig); + this.desiredReturnAction = desiredReturnAction; + this.desiredReturnConfigurationFile = desiredReturnConfigurationFile; + } + + @Override + public String getStringProp(String propName) { + // Would it be better making this file a static import? + if ( propName.equals( VALIDATOR_HTML_VALIDATION_ACTION ) ) { + return desiredReturnAction; + } else if ( propName.equals( VALIDATOR_HTML_VALIDATION_CONFIGURATION_FILE ) ) { + return desiredReturnConfigurationFile; + } else { + return super.getStringProp( propName ); + } + } + } + + // Must be public! + @Rule + public ExpectedException thrownEx = ExpectedException.none(); + + @After + public void tearDown() throws Exception { + ESAPI.override(null); + } + + @Before + public void setUp() throws Exception { + ESAPI.override( + new ConfOverride( ESAPI.securityConfiguration(), "throw", ANTISAMY_POLICY_FILE_NONSTANDARD_LOCATION ) + ); + } + + + @Test + public void checkPolicyExceptionWithBadConfig() throws Exception { + ESAPI.override(null); + thrownEx.expect(PolicyException.class); + HTMLValidationRule.loadAntisamyPolicy(INVALID_ANTISAMY_POLICY_FILE); + } + + @Test + public void testGetValid() throws Exception { + System.out.println("getValidCP"); + Validator instance = ESAPI.validator(); + HTMLValidationRule rule = new HTMLValidationRule("testCP"); + ESAPI.validator().addRule(rule); + + thrownEx.expect(ValidationException.class); + thrownEx.expectMessage("test: Invalid HTML input"); + + instance.getRule("testCP").getValid("test", "Test. "); + } + + @Test + public void testGetValidSafeHTML() throws Exception { + System.out.println("getValidSafeHTML"); + Validator instance = ESAPI.validator(); + + HTMLValidationRule rule = new HTMLValidationRule("test"); + ESAPI.validator().addRule(rule); + + String[] testInput = { + // These first two don't cause AntiSamy to throw. + // They are only listed here for completeness. + // "Test. Aspect Security", + // "Test. <
load=alert()", + "Test. ", + "Test. ", + "Test.
b
", + "Test. alert(document.cookie)", + "Test. alert(document.cookie)", + "Test. alert(document.cookie)" + }; + + int errors = 0; + for( int i = 0; i < testInput.length; i++ ) { + try { + String result = instance.getValidSafeHTML("test", testInput[i], 100, false); + errors++; + System.out.println("testGetValidSafeHTML(): testInput '" + testInput[i] + "' failed to throw."); + } + catch( ValidationException vex ) { + System.out.println("testGetValidSafeHTML(): testInput '" + testInput[i] + "' returned:"); + System.out.println("\t" + i + ": logMsg =" + vex.getLogMessage()); + assertEquals( vex.getUserMessage(), "test: Invalid HTML input"); + } + catch( Exception ex ) { + errors++; + System.out.println("testGetValidSafeHTML(): testInput '" + testInput[i] + + "' threw wrong exception type: " + ex.getClass().getName() ); + } + } + + if ( errors > 0 ) { + fail("testGetValidSafeHTML() encountered " + errors + " failures."); + } + } + +} diff --git a/src/test/java/org/owasp/esapi/reference/validation/HTMLValidationRuleCleanTest.java b/src/test/java/org/owasp/esapi/reference/validation/HTMLValidationRuleCleanTest.java new file mode 100644 index 000000000..964df6c1f --- /dev/null +++ b/src/test/java/org/owasp/esapi/reference/validation/HTMLValidationRuleCleanTest.java @@ -0,0 +1,408 @@ +/** + * 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) 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 kevin.w.wall@gmail.com + * @since 2019 + */ +package org.owasp.esapi.reference.validation; + +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.EncoderConstants; +import org.owasp.esapi.SecurityConfiguration; +import org.owasp.esapi.SecurityConfigurationWrapper; +import org.owasp.esapi.ValidationErrorList; +import org.owasp.esapi.ValidationRule; +import org.owasp.esapi.Validator; +import org.owasp.esapi.errors.IntrusionException; +import org.owasp.esapi.errors.ValidationException; +import org.owasp.esapi.filters.SecurityWrapperRequest; +import org.owasp.esapi.reference.validation.HTMLValidationRule; +import static org.owasp.esapi.PropNames.VALIDATOR_HTML_VALIDATION_ACTION; + +import org.junit.Test; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.After; +import org.junit.Rule; +import org.junit.rules.ExpectedException; +import static org.hamcrest.CoreMatchers.both; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +/** + * The Class HTMLValidationRuleCleanTest. + * + * Based on original test cases, testGetValidSafeHTML() and + * testIsValidSafeHTML() from ValidatorTest by + * Mike Fauzy (mike.fauzy@aspectsecurity.com) and + * Jeff Williams (jeff.williams@aspectsecurity.com) + * that were originally part of src/test/java/org/owasp/esapi/reference/ValidatorTest.java. + * + * This class tests the cases where the new ESAPI.property + * Validator.HtmlValidationAction + * is set to "clean", which causes certain calls to + * {@code ESAPI.validator().getValidSafeHTML()} + * to simply log a warning and return the cleansed (sanitized) output rather + * than throwing a ValidationException when certain unsafe input is + * encountered. + * + * @author kevin.w.wall@gmail.com + */ +public class HTMLValidationRuleCleanTest { + private static SecurityConfiguration origConfig = ESAPI.securityConfiguration(); + + private static class ConfOverride extends SecurityConfigurationWrapper { + private String desiredReturn = "clean"; + + ConfOverride(SecurityConfiguration orig, String desiredReturn) { + super(orig); + this.desiredReturn = desiredReturn; + } + + @Override + public String getStringProp(String propName) { + // Would it be better making this file a static import? + if ( propName.equals( VALIDATOR_HTML_VALIDATION_ACTION ) ) { + return desiredReturn; + } else { + return super.getStringProp( propName ); + } + } + } + + + /** + * Default constructor that instantiates a new {@code HTMLValidationRule} test. + */ + public HTMLValidationRuleCleanTest() { + } + + @After + public void tearDown() throws Exception { + ESAPI.override(null); + } + + @Before + public void setUp() throws Exception { + ESAPI.override( + new ConfOverride( origConfig, "clean" ) + ); + + } + + @Test + public void testGetValidSafeHTML() throws Exception { + System.out.println("testGetValidSafeHTML"); + Validator instance = ESAPI.validator(); + ValidationErrorList errors = new ValidationErrorList(); + + HTMLValidationRule rule = new HTMLValidationRule("test"); + ESAPI.validator().addRule(rule); + + assertEquals("Test.", ESAPI.validator().getRule("test").getValid("test", "Test. ")); + + String test1 = "Jeff"; + String result1 = instance.getValidSafeHTML("test", test1, 100, false, errors); + assertEquals(test1, result1); + + String test2 = "Aspect Security"; + String result2 = instance.getValidSafeHTML("test", test2, 100, false, errors); + assertEquals(test2, result2); + + String test3 = "Test. Cookie :-)"; + assertEquals("Test. Cookie :-)", rule.getSafe("test", test3)); + + assertEquals("Test. <
load=alert()
", rule.getSafe("test", "Test. <
load=alert()")); + assertEquals("Test.
b
", rule.getSafe("test", "Test.
b
")); + assertEquals("Test. alert(document.cookie)", rule.getSafe("test", "Test. alert(document.cookie)")); + assertEquals("Test. alert(document.cookie)", rule.getSafe("test", "Test. alert(document.cookie)")); + assertEquals("Test. alert(document.cookie)", rule.getSafe("test", "Test. alert(document.cookie)")); + } + + // Test to confirm that CVE-2022-24891 is fixed in ESAPI. The cause of this was + // from a subtly botched regex for 'onsiteURL' in all the versions of + // antsamy-esapi.xml that had been there as far back as ESAPI 1.4! + // + // This CVE should arguably get the same CVSSv3 score as the AntiSamy + // CVE-2021-35043 as they are very similar. + // + // Updated: Requested CVE from GitHub CNA on 4/23/2022. See also + // https://github.com/ESAPI/esapi-java-legacy/security/advisories/GHSA-q77q-vx4q-xx6q + @Test + public void testESAPI_CVE_2022_24891() throws Exception { + System.out.println("testESAPI_CVE_2022_24891"); + + String expectedSafeText = "This is safe from XSS. Trust us!"; + String badVoodoo = "" + expectedSafeText + ""; + Validator instance = ESAPI.validator(); + ValidationErrorList errorList = new ValidationErrorList(); + String result = instance.getValidSafeHTML("test", badVoodoo, 100, false, errorList); + assertEquals( expectedSafeText, result ); + } + + // To confirm fix for CVE-2021-35043 in AntiSamy 1.6.5 and later. Actually, + // it was never really "broken" in ESAPI's "default configuration" because it is + // triggers an Intrusion Detection when it is checking the canonicalization + // and the ':' trips it up, that that's pretty much irrelevant given + // the CVE mentioned in the previous test case. + // + // Note: This test assumes a standard default ESAPI.properties file. In + // particular, the normal canonicalization has to be enabled. + // + public void testAntiSamy_CVE_2021_35043Fixed() throws Exception { + System.out.println("testAntiSamy_CVE_2021_35043Fixed"); + + String expectedSafeText = "This is safe from XSS. Trust us!"; + + // Translates to '" + expectedSafeText + ""; + Validator instance = ESAPI.validator(); + String cleansed = instance.getValidSafeHTML("CVE-2021-35043", badVoodoo, 200, false); + assertEquals( "", cleansed ); + } + + ////////// New AntiSamy tests added to ESAPI 2.5.3.0 ////////// + // Some of these were with the new XSS discoveries in AntiSamy. + // Sebastian doesn't think thta ESAPI should be vulnerable to these 2. (They weren't.) + @Test + public void testQuotesInsideStyles() throws Exception { + System.out.println("testQuotesInsideStyles"); + Validator instance = ESAPI.validator(); + ValidationErrorList errors = new ValidationErrorList(); + + // Added this test because of a fix to AntiSamy that doesn't seem to have affected ESAPI because of our + // very restrictive default AntiSamy policy file. However, with some of AntiSamy policy files, this used + // to cause any quoted (double or single) string identifier in CSS was being enclosed in quotes. + // That resulted in quotes enclosed by more quotes in some cases without any kind of escape or + // transformation. It never did that for ESAPI, but it seemed like a good test to add. + String input = + "Safe Text"; + String expected = "Safe Text"; // We expect the span tag to be completely filtered out & only the tag contents to remain. + String output = instance.getValidSafeHTML("testQuotesInsideStyles-1", input, 250, false); + assertEquals(expected, output); + + input = "Safe Text"; // Slight variation + output = instance.getValidSafeHTML("testQuotesInsideStyle-2", input, 250, false); + assertEquals(expected, output); + + assertTrue(errors.size() == 0); + } + + @Test + public void testSmuggledTagsInStyleContentCase() throws Exception { + System.out.println("testSmuggledTagsInStyleContentCase"); + + Validator instance = ESAPI.validator(); + ValidationErrorList errors = new ValidationErrorList(); + + // Style tag processing was not handling correctly the value set to its child node that should + // be only text. On some mutation scenarios due to filtering tags by default, content was being + // smuggled and not properly sanitized by the output serializer. + // + // Not expected to affect ESAPI because our default AntiSamy policy file does NOT have: + // + // in it. + // + String input = "Safe stuff"; + String output = null; + String expected = null; + try { + expected = "Safe<listing/>]]><noembed> stuff"; + output = instance.getValidSafeHTML("testSmuggledTagsInStyleContentCase-1", input, 250, false, errors); + } catch (IntrusionException ex) { + fail("testSmuggledTagsInStyleContentCase-1 - should not happen."); + } + assertTrue(errors.size() == 0); + assertEquals(expected, output); + + input = "Safe' stuff"; + try { + expected = "Safe<math>'<noframes >' stuff"; + output = instance.getValidSafeHTML("testSmuggledTagsInStyleContentCase-2", input, 250, false, errors); + } catch (IntrusionException ex) { + fail("testSmuggledTagsInStyleContentCase-2 - should not happen."); + } + assertTrue(errors.size() == 0); + assertEquals(expected, output); + } + + @Test + public void testAntiSamy_CVE_2023_43643() { + System.out.println("testAntiSamy_CVE_2023_43643"); + // These are new tests are variations from AntiSamy 1.7.4 and were associted with CVE-2023-43643. (See + // https://github.com/nahsra/antisamy/security/advisories/GHSA-pcf2-gh6g-h5r2 for additional details.) + // The concern is that when preserving comments, certain tags would get their content badly parsed + // due to mutation XSS. Note that AntiSamy 1.7.3 and earlier had problems (depending on it's + // AntiSamy policy file) for all these constructs, but ESAPI using AntiSamy 1.7.3 had no vulnerabilities + // because our antisamy-esapi.xml AntiSamy policy file is much stricter. Regardless, these make good + // additions to our test suite. + String[] payloads = { + "