chore: add pre-commit hooks
chore: add pre-commit hooks chore: add pre-commit hooks chore: add pre-commit hooks chore: add pre-commit hooks
This commit is contained in:
@ -70,4 +70,3 @@ management.endpoints.web.exposure.include=env, health,configprops
|
||||
|
||||
spring.security.oauth2.client.registration.github.client-id=${WEBGOAT_OAUTH_CLIENTID:dummy}
|
||||
spring.security.oauth2.client.registration.github.client-secret=${WEBGOAT_OAUTH_CLIENTSECRET:dummy}
|
||||
|
||||
|
@ -63,4 +63,4 @@ CREATE TABLE CONTAINER.EMAIL(
|
||||
TITLE VARCHAR(255)
|
||||
);
|
||||
|
||||
ALTER TABLE CONTAINER.EMAIL ALTER COLUMN ID RESTART WITH 2;
|
||||
ALTER TABLE CONTAINER.EMAIL ALTER COLUMN ID RESTART WITH 2;
|
||||
|
@ -1,4 +1,3 @@
|
||||
ALTER TABLE CONTAINER.ASSIGNMENT ALTER COLUMN ID SET GENERATED BY DEFAULT AS IDENTITY(START WITH 1);
|
||||
ALTER TABLE CONTAINER.LESSON_TRACKER ALTER COLUMN ID SET GENERATED BY DEFAULT AS IDENTITY(START WITH 1);
|
||||
ALTER TABLE CONTAINER.USER_TRACKER ALTER COLUMN ID SET GENERATED BY DEFAULT AS IDENTITY(START WITH 1);
|
||||
|
||||
|
@ -53,7 +53,7 @@ reset.lesson=Reset lesson
|
||||
sign.in=Sign in
|
||||
register.new=or register yourself as a new user
|
||||
sign.up=Sign up
|
||||
register.title=Register
|
||||
register.title=Register
|
||||
searchmenu=Search lesson
|
||||
|
||||
|
||||
@ -66,7 +66,7 @@ security.enabled=Security enabled, you can try the previous challenges and see t
|
||||
security.disabled=Security enabled, you can try the previous challenges and see the effect!
|
||||
termsofuse=Terms of use
|
||||
register.condition.1=While running this program your machine will be extremely vulnerable to attack.\
|
||||
You should disconnect from the Internet while using this program. WebGoat's default configuration binds to localhost to minimize the exposure.
|
||||
You should disconnect from the Internet while using this program. WebGoat's default configuration binds to localhost to minimize the exposure.
|
||||
register.condition.2=This program is for educational purposes only. If you attempt \
|
||||
these techniques without authorization, you are very likely to get caught. If \
|
||||
you are caught engaging in unauthorized hacking, most companies will fire you. \
|
||||
|
@ -37,5 +37,4 @@ username=Benutzername
|
||||
password=Passwort
|
||||
password.confirm=Wiederhohl Passwort
|
||||
sign.up=Anmelden
|
||||
register.title=Registrieren
|
||||
|
||||
register.title=Registrieren
|
||||
|
@ -59,4 +59,4 @@ register.condition.1=Wanneer u WebGoat runt op uw computer, bent u kwetsbaar voo
|
||||
Zorg dat u geen verbinding heeft met internet en dat toegang tot WebGoat alleen lokaal mogelijk is om het aanvalsoppervlak te verkleinen.
|
||||
register.condition.2=WebGoat is bedoeld als educatieve applicatie op het gebied van secure software development. \
|
||||
Gebruik wat u leert om applicaties beter te maken en niet om zonder toestemming applicaties te schaden. \
|
||||
In dat laatste geval loopt u risico op rechtsvervoling en ontslag.
|
||||
In dat laatste geval loopt u risico op rechtsvervoling en ontslag.
|
||||
|
@ -8,4 +8,3 @@ auth-bypass.hints.verify.1=The attack on this is similar to the story referenced
|
||||
auth-bypass.hints.verify.2=You do want to tamper the security question parameters, but not delete them
|
||||
auth-bypass.hints.verify.3=The logic to verify the account does expect 2 security questions to be answered, but there is a flaw in the implementation
|
||||
auth-bypass.hints.verify.4=Have you tried renaming the secQuestion0 and secQuestion1 parameters?
|
||||
|
||||
|
@ -2,4 +2,4 @@
|
||||
position: relative;
|
||||
padding: 7px;
|
||||
margin-top: 7px;
|
||||
}
|
||||
}
|
||||
|
@ -40,4 +40,4 @@
|
||||
}
|
||||
.review-block-description{
|
||||
font-size:13px;
|
||||
}
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
The admin forgot where the password is stashed, can you help?
|
||||
The admin forgot where the password is stashed, can you help?
|
||||
|
@ -1 +1 @@
|
||||
Can you login as Larry?
|
||||
Can you login as Larry?
|
||||
|
@ -1 +1 @@
|
||||
Can you login as Tom? It may be a little harder than it was for Larry.
|
||||
Can you login as Tom? It may be a little harder than it was for Larry.
|
||||
|
@ -1 +1 @@
|
||||
Can you still vote?
|
||||
Can you still vote?
|
||||
|
@ -26,4 +26,4 @@ an e-mail.
|
||||
Team WebGoat
|
||||
|
||||
|
||||
image::images/boss.jpg[]
|
||||
image::images/boss.jpg[]
|
||||
|
@ -19,9 +19,9 @@ input.invalid=Input for user, email and/or password is empty or too long, please
|
||||
challenge.flag.correct=Congratulations you have solved the challenge!!
|
||||
challenge.flag.incorrect=Sorry this is not the correct flag, please try again.
|
||||
|
||||
ip.address.unknown=IP address unknown, e-mail has been sent.
|
||||
ip.address.unknown=IP address unknown, e-mail has been sent.
|
||||
|
||||
|
||||
|
||||
required4=Missing username or password, please specify both.
|
||||
user.not.larry=Please try to log in as Larry not {0}.
|
||||
user.not.larry=Please try to log in as Larry not {0}.
|
||||
|
File diff suppressed because one or more lines are too long
@ -15,4 +15,4 @@ $(function() {
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
@ -54,4 +54,4 @@ function doVote(stars) {
|
||||
})
|
||||
loadVotes();
|
||||
average();
|
||||
}
|
||||
}
|
||||
|
@ -37,4 +37,4 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
#lesson_wrapper {height: 435px;width: 500px;}
|
||||
#lesson_header {background-image: url(../images/lesson1_header.jpg); width: 490px;padding-right: 10px;padding-top: 60px;background-repeat: no-repeat;}
|
||||
.lesson_workspace {background-image: url(../images/lesson1_workspace.jpg); width: 490px;height: 325px;padding-left: 10px;padding-top: 10px;background-repeat: no-repeat;}
|
||||
.lesson_workspace {background-image: url(../images/lesson1_workspace.jpg); width: 490px;height: 325px;padding-left: 10px;padding-top: 10px;background-repeat: no-repeat;}
|
||||
|
@ -30,4 +30,4 @@ div.section > div > input {margin:0px;padding-left:5px;font-size:10px;padding-ri
|
||||
}
|
||||
.section{width:104%;}
|
||||
.menu-items{padding-left:0px;}
|
||||
}
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
No need to pay if you know the code ...
|
||||
No need to pay if you know the code ...
|
||||
|
@ -164,6 +164,3 @@
|
||||
</div>
|
||||
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
client.side.filtering.title=Client side filtering
|
||||
ClientSideFilteringSelectUser=Select user:
|
||||
ClientSideFilteringSelectUser=Select user:
|
||||
ClientSideFilteringUserID=User ID
|
||||
ClientSideFilteringFirstName=First Name
|
||||
ClientSideFilteringLastName=Last Name
|
||||
ClientSideFilteringSSN=SSN
|
||||
ClientSideFilteringSalary=Salary
|
||||
ClientSideFilteringErrorGenerating=Error generating
|
||||
ClientSideFilteringErrorGenerating=Error generating
|
||||
ClientSideFilteringStage1Complete=Stage 1 completed.
|
||||
ClientSideFilteringStage1Question=What is Neville Bartholomew's salary?
|
||||
ClientSideFilteringStage1Question=What is Neville Bartholomew's salary?
|
||||
ClientSideFilteringStage1SubmitAnswer=Submit Answer
|
||||
ClientSideFilteringStage2Finish=Click here when you believe you have completed the lesson.
|
||||
ClientSideFilteringChoose=Choose employee
|
||||
@ -16,7 +16,7 @@ ClientSideFilteringHint2=Use Firebug to find where the information is stored on
|
||||
ClientSideFilteringHint3=Examine the hidden table to see if there is anyone listed who is not in the drop down menu.
|
||||
ClientSideFilteringHint4=Look in the last row of the hidden table.
|
||||
ClientSideFilteringHint5a=Stage 1: You can access the server directly
|
||||
ClientSideFilteringHint5b=here
|
||||
ClientSideFilteringHint5b=here
|
||||
ClientSideFilteringHint5c=to see what results are being returned
|
||||
ClientSideFilteringHint6=Stage 2: The server uses an XPath query against an XML database.
|
||||
ClientSideFilteringHint7=Stage 2: The query currently returns all of the contents of the database.
|
||||
|
@ -39,4 +39,4 @@ function ajaxFunction(userId) {
|
||||
var container = document.getElementById("hiddenEmployeeRecords");
|
||||
container.appendChild(newdiv);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -61,4 +61,4 @@ $(document).ready(function () {
|
||||
$('#price').text(quantity * 899);
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
@ -9,29 +9,29 @@
|
||||
<p><b>Lesson Plan Title:</b> Client Side Filtering</p>
|
||||
|
||||
<p><b>Concept / Topic To Teach:</b><br/>
|
||||
It is always a good practice to send to the client
|
||||
only information which they are supposed to have access to.
|
||||
In this lesson, too much information is being sent to the
|
||||
It is always a good practice to send to the client
|
||||
only information which they are supposed to have access to.
|
||||
In this lesson, too much information is being sent to the
|
||||
client, creating a serious access control problem.
|
||||
</p>
|
||||
</p>
|
||||
|
||||
<p><b>General Goal(s):</b><br/>
|
||||
For this exercise, your mission is exploit the extraneous
|
||||
information being returned by the server to discover information
|
||||
to which you should not have access.
|
||||
For this exercise, your mission is exploit the extraneous
|
||||
information being returned by the server to discover information
|
||||
to which you should not have access.
|
||||
</p>
|
||||
|
||||
<b>Solution:</b><br/>
|
||||
<p>
|
||||
This Lab consists of two Stages. In the first Stage you have to
|
||||
This Lab consists of two Stages. In the first Stage you have to
|
||||
get sensitive information . In the second one you have to fix the problem.<br/>
|
||||
</p>
|
||||
<b>Stage 1</b>
|
||||
<p>
|
||||
Use Firebug to solve this stage. If you are using IE you can try it with
|
||||
Use Firebug to solve this stage. If you are using IE you can try it with
|
||||
IEWatch.</p>
|
||||
|
||||
First use any person from the list and see what you get. After doing this you
|
||||
First use any person from the list and see what you get. After doing this you
|
||||
can search for a specific person in Firebug. Make sure you find the hidden table with
|
||||
the information, including the salary and so on. In the same table you will find
|
||||
Neville.
|
||||
@ -44,36 +44,36 @@ Now write the salary into the text edit box and submit your answer!
|
||||
</p>
|
||||
<b>Stage 2</b>
|
||||
<p>
|
||||
In this stage you have to modify the clientSideFiltering.jsp which you will find under
|
||||
In this stage you have to modify the clientSideFiltering.jsp which you will find under
|
||||
the WebContent in the lessons/Ajax folder. The Problem is that
|
||||
the server sends all information to the client. As you could see
|
||||
even if it is hidden it is easy to find the sensitive date. In this
|
||||
stage you will add a filter to the XPath queries. In this file you will find
|
||||
stage you will add a filter to the XPath queries. In this file you will find
|
||||
following construct:<br><br></p>
|
||||
<code>
|
||||
StringBuilder sb = new StringBuilder();<br>
|
||||
|
||||
|
||||
sb.append("/Employees/Employee/UserID | ");<br>
|
||||
sb.append("/Employees/Employee/FirstName | ");<br>
|
||||
sb.append("/Employees/Employee/LastName | ");<br>
|
||||
sb.append("/Employees/Employee/SSN | ");<br>
|
||||
sb.append("/Employees/Employee/Salary ");<br>
|
||||
|
||||
|
||||
String expression = sb.toString();<br>
|
||||
</code>
|
||||
<p>
|
||||
This string will be used for the XPath query. You have to guarantee that a manger only
|
||||
This string will be used for the XPath query. You have to guarantee that a manger only
|
||||
can see employees which are working for him. To archive this you can use
|
||||
filters in XPath. Following code will exactly do this:</p>
|
||||
<code>
|
||||
StringBuilder sb = new StringBuilder();<br>
|
||||
|
||||
|
||||
sb.append("/Employees/Employee[Managers/Manager/text() = " + userId + "]/UserID | ");<br>
|
||||
sb.append("/Employees/Employee[Managers/Manager/text() = " + userId + "]/FirstName | ");<br>
|
||||
sb.append("/Employees/Employee[Managers/Manager/text() = " + userId + "]/LastName | ");<br>
|
||||
sb.append("/Employees/Employee[Managers/Manager/text() = " + userId + "]/SSN | ");<br>
|
||||
sb.append("/Employees/Employee[Managers/Manager/text() = " + userId + "]/Salary ");<br>
|
||||
|
||||
|
||||
String expression = sb.toString();<br>
|
||||
</code>
|
||||
<p>
|
||||
|
@ -1,6 +1,6 @@
|
||||
= Cryptography Basics
|
||||
|
||||
== Concept
|
||||
= Cryptography Basics
|
||||
|
||||
== Concept
|
||||
|
||||
ifeval::["{lang}" == "nl"]
|
||||
Deze les behandelt verschillende cryptografische technieken die voorkomen in webapplicaties.
|
||||
@ -31,5 +31,3 @@ The goal is to get familiar with the following forms of techniques:
|
||||
=== Assignments
|
||||
|
||||
After the explanation of an item there will be several assignments.
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
= Security defaults
|
||||
= Security defaults
|
||||
|
||||
A big problem in all kinds of systems is the use of default configurations.
|
||||
E.g. default username/passwords in routers, default passwords for keystores, default unencrypted mode, etc.
|
||||
@ -15,10 +15,10 @@ Are you using an ssh key for GitHub and or other sites and are you leaving it un
|
||||
|
||||
When you are getting a virtual server from some hosting provider, there are usually a lot of not so secure defaults. One of which is that ssh to the server runs on the default port 22 and allows username/password attempts. One of the first things you should do, is to change the configuration that you cannot ssh as user root, and you cannot ssh using username/password, but only with a valid and strong ssh key. If not, then you will notice continuous brute force attempts to login to your server.
|
||||
|
||||
|
||||
|
||||
== Assignment
|
||||
|
||||
In this exercise you need to retrieve a secret that has accidentally been left inside a docker container image. With this secret, you can decrypt the following message: *U2FsdGVkX199jgh5oANElFdtCxIEvdEvciLi+v+5loE+VCuy6Ii0b+5byb5DXp32RPmT02Ek1pf55ctQN+DHbwCPiVRfFQamDmbHBUpD7as=*.
|
||||
In this exercise you need to retrieve a secret that has accidentally been left inside a docker container image. With this secret, you can decrypt the following message: *U2FsdGVkX199jgh5oANElFdtCxIEvdEvciLi+v+5loE+VCuy6Ii0b+5byb5DXp32RPmT02Ek1pf55ctQN+DHbwCPiVRfFQamDmbHBUpD7as=*.
|
||||
You can decrypt the message by logging in to the running container (docker exec ...) and getting access to the password file located in /root. Then use the openssl command inside the container (for portability issues in openssl on Windows/Mac/Linux)
|
||||
You can find the secret in the following docker image, which you can start as:
|
||||
|
||||
@ -28,6 +28,3 @@ You can find the secret in the following docker image, which you can start as:
|
||||
----
|
||||
echo "U2FsdGVkX199jgh5oANElFdtCxIEvdEvciLi+v+5loE+VCuy6Ii0b+5byb5DXp32RPmT02Ek1pf55ctQN+DHbwCPiVRfFQamDmbHBUpD7as=" | openssl enc -aes-256-cbc -d -a -kfile ....
|
||||
----
|
||||
|
||||
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
= Cryptography Basics
|
||||
|
||||
== Base64 Encoding
|
||||
= Cryptography Basics
|
||||
|
||||
Encoding is not really cryptography, but it is used a lot in all kinds of standards around cryptographic functions. Especially Base64 encoding.
|
||||
== Base64 Encoding
|
||||
|
||||
Encoding is not really cryptography, but it is used a lot in all kinds of standards around cryptographic functions. Especially Base64 encoding.
|
||||
|
||||
Base64 encoding is a technique used to transform all kinds of bytes to a specific range of bytes. This specific range is the ASCII readable bytes.
|
||||
This way you can transfer binary data such as secret or private keys more easily. You could even print these out or write them down.
|
||||
@ -11,7 +11,7 @@ Encoding is also reversible. So if you have the encoded version, you can create
|
||||
On wikipedia you can find more details. Basically it goes through all the bytes and transforms each set of 6 bits into a readable byte (8 bits). The result is that the size of the encoded bytes is increased with about 33%.
|
||||
|
||||
Hello ==> SGVsbG8=
|
||||
0x4d 0x61 ==> TWE=
|
||||
0x4d 0x61 ==> TWE=
|
||||
|
||||
=== Basic Authentication
|
||||
|
||||
@ -19,8 +19,7 @@ Basic authentication is sometimes used by web applications. This uses base64 enc
|
||||
|
||||
$echo -n "myuser:mypassword" | base64
|
||||
bXl1c2VyOm15cGFzc3dvcmQ=
|
||||
|
||||
|
||||
The HTTP header will look like:
|
||||
|
||||
|
||||
Authorization: Basic bXl1c2VyOm15cGFzc3dvcmQ=
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
= Cryptography Basics
|
||||
|
||||
== Other Encoding
|
||||
= Cryptography Basics
|
||||
|
||||
Also other encodings are used.
|
||||
== Other Encoding
|
||||
|
||||
Also other encodings are used.
|
||||
|
||||
=== URL encoding
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
= Encryption
|
||||
|
||||
== Symmetric encryption
|
||||
= Encryption
|
||||
|
||||
== Symmetric encryption
|
||||
|
||||
Symmetric encryption is based on a shared secret that is used for both encryption as well as decryption. Therefore, both parties (that are involved in exchanging secrets) share the same key.
|
||||
|
||||
@ -12,7 +12,7 @@ Example protocols are:
|
||||
== Asymmetric encryption
|
||||
|
||||
Asymmetric encryption is based on mathematical principles that consist of a key pair. The two keys are usually called a private key and a public key. The private key needs to be protected very well and is only known to one party. All others can freely use the public key. Something encrypted with the private key can be decrypted by all that have the public key, and something encrypted with the public key can only be decrypted with the private key.
|
||||
|
||||
|
||||
Example protocols are:
|
||||
|
||||
* RSA
|
||||
@ -28,5 +28,3 @@ Here is a short description of what happens if you open your browser and go to a
|
||||
* At the end of this process both the browser and the webserver will use the exchanged symmetric key (in the asymmetric key exchange process) to encrypt and decrypt messages that are sent back and forth between the browser and the webserver.
|
||||
|
||||
Symmetric keys are used because it can be used more easily with large sets of data and requires less processing power in doing so. However, the information on these pages is just for a basic understanding of cryptography. Look on the internet for more detailed information about these topics.
|
||||
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
= Cryptography Basics
|
||||
|
||||
== Plain Hashing
|
||||
= Cryptography Basics
|
||||
|
||||
Hashing is a type of cryptography which is mostly used to detect if the original data has been changed. A hash is generated from the original data. It is based on irreversible cryptographic techniques.
|
||||
== Plain Hashing
|
||||
|
||||
Hashing is a type of cryptography which is mostly used to detect if the original data has been changed. A hash is generated from the original data. It is based on irreversible cryptographic techniques.
|
||||
If the original data is changed by even one byte, the resulting hash is also different.
|
||||
|
||||
So in a way it looks like a secure technique. However, it is NOT and even NEVER a good solution when using it for passwords. The problem here is that you can generate passwords from dictionaries and calculate all kinds of variants from these passwords. For each password you can calculate a hash. This can all be stored in large databases. So whenever you find a hash that could be a password, you just look up the hash in the database and find out the password.
|
||||
|
@ -1,35 +1,35 @@
|
||||
= Keystores & Truststores
|
||||
|
||||
A keystore is a place where you store keys. Besides *_keystore_* the term *_truststore_* is also used frequently. A truststore is the same thing as a keystore. Only it usually contains only the certificates (so basically only public keys and issuer information) of trusted certificates or certificate authorities.
|
||||
|
||||
== File based keystores
|
||||
A keystore is a place where you store keys. Besides *_keystore_* the term *_truststore_* is also used frequently. A truststore is the same thing as a keystore. Only it usually contains only the certificates (so basically only public keys and issuer information) of trusted certificates or certificate authorities.
|
||||
|
||||
== File based keystores
|
||||
|
||||
A file based keystore is something that in the end has the keys on a file system.
|
||||
Storing public certificates in a file based keystore is very common
|
||||
|
||||
== Database keystores
|
||||
|
||||
Keys and especially public certificates can of course also be stored in a database.
|
||||
Keys and especially public certificates can of course also be stored in a database.
|
||||
|
||||
== Hardware keystore
|
||||
|
||||
A hardware keystore is a system that has some sort of hardware which contain the actual keys.
|
||||
This is typically done in high end security environments where the private key is really private.
|
||||
In comparison with file based or database keystores, it is impossible to make a copy of the keystore to send it to some unknown and untrusted environment.
|
||||
In comparison with file based or database keystores, it is impossible to make a copy of the keystore to send it to some unknown and untrusted environment.
|
||||
|
||||
Some certificate authorities that are used to provide you with a server certificate for your website, also create the private keys for you (as-a-service). However, it is by definition no longer considered a private key. For all keystore types, you should keep the private key private and use a certificate signing request to order your signing or server certificates.
|
||||
|
||||
== Managed keystores in operating system, browser and other applications
|
||||
|
||||
When you visit a website and your browser says that the certificates are fine, it means that the certificate used for the website is issued by a trusted certificate authority. But this list of trusted certificate authorities is managed. Some CA's might be revoked or removed. These updates happen in the background when browser updates are installed.
|
||||
When you visit a website and your browser says that the certificates are fine, it means that the certificate used for the website is issued by a trusted certificate authority. But this list of trusted certificate authorities is managed. Some CA's might be revoked or removed. These updates happen in the background when browser updates are installed.
|
||||
Not only the browser maintains a list of trusted certificate authorities, the operation system does so as well. And the Java runtime also has its own list which is kept in the cacerts file. Updates of the OS and Java JRE keep this list up to date. In corporate environments, these are usually maintained by the company and also contain company root certificates.
|
||||
|
||||
== Extra check for website certificates using DNS CAA records
|
||||
|
||||
Some companies inspect all or most internet traffic. Even the ones were you think you have an end-2-end secured connection. This works as follows. An employee opens a browser and googles some information. The browser will use https and go to the site of google. The link looks real and the lock is shown in the browser. However, if you would inspect the certificate, you might notice that it has been issued by one of your companies root CA's! So you have established an end-2-end secure connection with a server of your company, and that server has the secure connection with google.
|
||||
Some companies inspect all or most internet traffic. Even the ones were you think you have an end-2-end secured connection. This works as follows. An employee opens a browser and googles some information. The browser will use https and go to the site of google. The link looks real and the lock is shown in the browser. However, if you would inspect the certificate, you might notice that it has been issued by one of your companies root CA's! So you have established an end-2-end secure connection with a server of your company, and that server has the secure connection with google.
|
||||
In order to prevent such man in the middle connections to your server, modern browsers now will also check the DNS CAA records to see whether or not a certain issuer is allowed for a certain website.
|
||||
More information: https://en.wikipedia.org/wiki/DNS_Certification_Authority_Authorization[Wiki DNS CAA,window=_blank]
|
||||
More information: https://en.wikipedia.org/wiki/DNS_Certification_Authority_Authorization[Wiki DNS CAA,window=_blank]
|
||||
|
||||
== Free certificates from Let's encrypt
|
||||
|
||||
https://letsencrypt.org[Let's encrypt,,window=_blank] is a free, automated and open Certificate Authority. It allows you to create valid certificates for the websites that you control. By following and implementing a certain protocol, your identity is checked and a certificate will be issued. The certificates are free of charge and this is done to stimulate the use of authorised certificates and to lower the use of self-signed certificates on the internet. Certificates are valid for 90 days, so they need to be automatically renewed. (Which makes sure that the proof of identity/ownership also takes place frequently)
|
||||
https://letsencrypt.org[Let's encrypt,,window=_blank] is a free, automated and open Certificate Authority. It allows you to create valid certificates for the websites that you control. By following and implementing a certain protocol, your identity is checked and a certificate will be issued. The certificates are free of charge and this is done to stimulate the use of authorised certificates and to lower the use of self-signed certificates on the internet. Certificates are valid for 90 days, so they need to be automatically renewed. (Which makes sure that the proof of identity/ownership also takes place frequently)
|
||||
|
@ -1,12 +1,12 @@
|
||||
= Signing
|
||||
= Signing
|
||||
|
||||
A signature is a hash that can be used to check the validity of some data. The signature can be supplied separately from the data that it validates, or in the case of CMS or SOAP can be included in the same file. (Where parts of that file contain the data and parts contain the signature).
|
||||
|
||||
Signing is used when integrity is important. It is meant to be a guarantee that data sent from Party-A to Party-B was not altered. So Party-A signs the data by calculating the hash of the data and encrypting that hash using an asymmetric private key. Party-B can then verify the data by calculating the hash of the data and decrypting the signature to compare if both hashes are the same.
|
||||
|
||||
== RAW signatures
|
||||
|
||||
A raw signature is usually calculated by Party-A as follows:
|
||||
== RAW signatures
|
||||
|
||||
A raw signature is usually calculated by Party-A as follows:
|
||||
|
||||
* create a hash of the data (e.g. SHA-256 hash)
|
||||
* encrypt the hash using an asymmetric private key (e.g. RSA 2048 bit key)
|
||||
@ -20,7 +20,7 @@ A CMS signature is a standardized way to send data + signature + certificate wit
|
||||
|
||||
== SOAP signatures
|
||||
|
||||
A SOAP signature also contains data and the signature and optionally the certificate. All in one XML payload. There are special steps involved in calculating the hash of the data. This has to do with the fact that the SOAP XML sent from system to system might introduce extra elements or timestamps.
|
||||
A SOAP signature also contains data and the signature and optionally the certificate. All in one XML payload. There are special steps involved in calculating the hash of the data. This has to do with the fact that the SOAP XML sent from system to system might introduce extra elements or timestamps.
|
||||
Also, SOAP Signing offers the possibility to sign different parts of the message by different parties.
|
||||
|
||||
|
||||
@ -36,5 +36,3 @@ Governments usually send official documents with a PDF that contains a certifica
|
||||
== Assignment
|
||||
|
||||
Here is a simple assignment. A private RSA key is sent to you. Determine the modulus of the RSA key as a hex string, and calculate a signature for that hex string using the key. The exercise requires some experience with OpenSSL. You can search on the Internet for useful commands and/or use the HINTS button to get some tips.
|
||||
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
<header>
|
||||
<script>
|
||||
/**
|
||||
* JavaScript to load initial assignment tokens
|
||||
* JavaScript to load initial assignment tokens
|
||||
*/
|
||||
function initialise() {
|
||||
$("#sha256token").load('crypto/hashing/sha256');
|
||||
@ -29,15 +29,15 @@ $(document).ready(initialise);
|
||||
Now suppose you have intercepted the following header:<br/>
|
||||
<div id="basicauthtoken" ></div><br/>
|
||||
<form class="attack-form" method="POST" name="form" action="crypto/encoding/basic-auth">
|
||||
Then what was the username
|
||||
Then what was the username
|
||||
<input name="answer_user" value="" type="TEXT"/>
|
||||
and what was the password:
|
||||
and what was the password:
|
||||
<input name="answer_pwd" value="" type="TEXT"/>
|
||||
<input name="SUBMIT" value="post the answer" type="SUBMIT"/>
|
||||
</form>
|
||||
<div class="attack-feedback"></div>
|
||||
<div class="attack-output"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 3. encoding xor -->
|
||||
<div class="lesson-page-wrapper">
|
||||
@ -71,9 +71,9 @@ $(document).ready(initialise);
|
||||
</form>
|
||||
<div class="attack-feedback"></div>
|
||||
<div class="attack-output"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 5. encryption -->
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="~{doc:lessons/cryptography/documentation/encryption.adoc}"></div>
|
||||
@ -88,9 +88,9 @@ $(document).ready(initialise);
|
||||
Now suppose you have the following private key:<br/>
|
||||
<pre><div id="privatekey" ></div></pre><br/>
|
||||
<form class="attack-form" method="POST" name="form" action="crypto/signing/verify">
|
||||
Then what was the modulus of the public key
|
||||
Then what was the modulus of the public key
|
||||
<input name="modulus" value="" type="TEXT"/>
|
||||
and now provide a signature for us based on that modulus
|
||||
and now provide a signature for us based on that modulus
|
||||
<input name="signature" value="" type="TEXT"/>
|
||||
<input name="SUBMIT" value="post the answer" type="SUBMIT"/>
|
||||
</form>
|
||||
@ -98,12 +98,12 @@ $(document).ready(initialise);
|
||||
<div class="attack-output"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 7. keystores -->
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="~{doc:lessons/cryptography/documentation/keystores.adoc}"></div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 8. security defaults -->
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="~{doc:lessons/cryptography/documentation/defaults.adoc}"></div>
|
||||
|
@ -12,9 +12,9 @@ crypto-hashing.hints.2=Find a online hash database or just google on the hash it
|
||||
|
||||
crypto-signing.hints.1=Use openssl to get the public key from the private key. Apparently both private and public key information are stored.
|
||||
crypto-signing.hints.2=Use the private key to sign the "modulus" value of the public key.
|
||||
crypto-signing.hints.3=Actually the "modulus" of the public key is the same as the private key. You could use openssl rsa -in test.key -pubout > test.pub and then openssl rsa -in test.pub -pubin -modulus -noout or other components.
|
||||
crypto-signing.hints.3=Actually the "modulus" of the public key is the same as the private key. You could use openssl rsa -in test.key -pubout > test.pub and then openssl rsa -in test.pub -pubin -modulus -noout or other components.
|
||||
crypto-signing.hints.4=Make sure that you do not take hidden characters into account. You might want to use echo -n "00AE89..." | openssl dgst -sign somekey -sha256 ... and do not forget to base64 encode the outcome
|
||||
|
||||
|
||||
|
||||
crypto-signing.notok=The signature does not match the data (modulus)
|
||||
crypto-signing.modulusnotok=The modulus is not correct
|
||||
|
@ -72,4 +72,4 @@
|
||||
}
|
||||
.post .post-footer .comments-list .comment > .comments-list {
|
||||
margin-left: 50px;
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
== Confirm Flag
|
||||
|
||||
Confirm the flag you should have gotten on the previous page below.
|
||||
Confirm the flag you should have gotten on the previous page below.
|
||||
|
@ -20,4 +20,4 @@ POST /csrf/feedback/message HTTP/1.1
|
||||
More information can be found http://pentestmonkey.net/blog/csrf-xml-post-request[here]
|
||||
|
||||
Remember you need to make the call from another origin (WebWolf can help here) and you need to be logged in into
|
||||
WebGoat.
|
||||
WebGoat.
|
||||
|
@ -20,8 +20,3 @@ with the server are performed with JavaScript. On the server side you only need
|
||||
if this header is not present deny the request.
|
||||
Some frameworks offer this implementation by default however researcher Alex Infuhr found out that this can be bypassed
|
||||
as well. You can read about: https://insert-script.blogspot.com/2018/05/adobe-reader-pdf-client-side-request.html[Adobe Reader PDF - Client Side Request Injection]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -6,5 +6,3 @@ This is the most simple CSRF attack to perform. For example you receive an e-mai
|
||||
|
||||
If the user is still logged in to the website of bank.com this simple GET request will transfer money from one account to another.
|
||||
Of course in most cases the website might have multiple controls to approve the request.
|
||||
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
== Basic Get CSRF Exercise
|
||||
|
||||
Trigger the form below from an external source while logged in. The response will include a 'flag' (a numeric value).
|
||||
|
||||
|
@ -43,4 +43,4 @@ ____
|
||||
|
||||
{nbsp} +
|
||||
Both Firefox and Chrome fixed this issue, but it shows why you should implement a CSRF protection instead
|
||||
of relying on the content-type of your APIs.
|
||||
of relying on the content-type of your APIs.
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
== Login CSRF attack
|
||||
|
||||
In a login CSRF attack, the attacker forges a login request to an honest site using the attacker’s username
|
||||
and password at that site. If the forgery succeeds, the honest server responds with a `Set-Cookie` header
|
||||
In a login CSRF attack, the attacker forges a login request to an honest site using the attacker’s username
|
||||
and password at that site. If the forgery succeeds, the honest server responds with a `Set-Cookie` header
|
||||
that instructs the browser to mutate its state by storing a session cookie, logging the user into
|
||||
the honest site as the attacker. This session cookie is used to bind subsequent requests to the user's session and hence
|
||||
to the attacker's authentication credentials. Login CSRF attacks can have serious consequences, for example
|
||||
to the attacker's authentication credentials. Login CSRF attacks can have serious consequences, for example
|
||||
see the picture below where an attacker created an account at google.com the victim visits the malicious
|
||||
website and the user is logged in as the attacker. The attacker could then later on gather information about
|
||||
the activities of the user.
|
||||
|
@ -6,4 +6,3 @@ finding somewhere that you want to execute the CSRF attack. The classic example
|
||||
|
||||
But we're keeping it simple here. In this case, you just need to trigger a review submission on behalf of the currently
|
||||
logged in user.
|
||||
|
||||
|
@ -21,7 +21,3 @@ something. Forcing the victim to retrieve data doesn't benefit an attacker becau
|
||||
As such, CSRF attacks target state-changing requests.
|
||||
|
||||
Let's continue with some exercises to address way to perform a CSRF request.
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -29,4 +29,4 @@ csrf-login-hint1=First create a new account with csrf-username
|
||||
csrf-login-hint2=Create a form which will log you in as this user (hint 1) and upload it to WebWolf
|
||||
csrf-login-hint3=Visit this assignment again
|
||||
csrf-login-success=Congratulations, now log out and login with your normal user account within WebGoat, remember the attacker knows you solved this assignment
|
||||
csrf-login-failed=The solution is not correct, you are clicking the button while logged in as {0}
|
||||
csrf-login-failed=The solution is not correct, you are clicking the button while logged in as {0}
|
||||
|
@ -43,4 +43,4 @@ $(document).ready(function () {
|
||||
|
||||
});
|
||||
}
|
||||
})
|
||||
})
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
It is weird (but it could happen) to find a gadget that runs dangerous actions itself when is deserialized. However, it is much easier to find a gadget that runs action on other gadget when it is deserialized, and that second gadget runs more actions on a third gadget, and so on until a real dangerous action is triggered. That set of gadgets that can be used in a deserialization process to achieve dangerous actions is called "Gadget Chain".
|
||||
|
||||
Finding gadgets to build gadget chains is an active topic for security researchers. This kind of research usually requires to spend a big amount of time reading code.
|
||||
Finding gadgets to build gadget chains is an active topic for security researchers. This kind of research usually requires to spend a big amount of time reading code.
|
||||
|
@ -7,4 +7,4 @@ This lesson describes what is Serialization and how it can be manipulated to per
|
||||
* The user should have a basic understanding of Java programming language
|
||||
* The user will be able to detect insecure deserialization vulnerabilities
|
||||
* The user will be able to exploit insecure deserialization vulnerabilities
|
||||
* Exploiting deserialization is slightly different in other programming languages such as PHP or Python, but the key concepts learnt here also applies to all of them
|
||||
* Exploiting deserialization is slightly different in other programming languages such as PHP or Python, but the key concepts learnt here also applies to all of them
|
||||
|
@ -36,7 +36,7 @@ public class VulnerableTaskHolder implements Serializable {
|
||||
private String taskName;
|
||||
private String taskAction;
|
||||
private LocalDateTime requestedExecutionTime;
|
||||
|
||||
|
||||
public VulnerableTaskHolder(String taskName, String taskAction) {
|
||||
super();
|
||||
this.taskName = taskName;
|
||||
@ -47,7 +47,7 @@ public class VulnerableTaskHolder implements Serializable {
|
||||
private void readObject( ObjectInputStream stream ) throws Exception {
|
||||
//deserialize data so taskName and taskAction are available
|
||||
stream.defaultReadObject();
|
||||
|
||||
|
||||
//blindly run some code. #code injection
|
||||
Runtime.getRuntime().exec(taskAction);
|
||||
}
|
||||
@ -67,4 +67,4 @@ ObjectOutputStream oos = new ObjectOutputStream(bos);
|
||||
oos.writeObject(go);
|
||||
oos.flush();
|
||||
byte[] exploit = bos.toByteArray();
|
||||
----
|
||||
----
|
||||
|
@ -5,4 +5,4 @@ The following input box receives a serialized object (a string) and it deseriali
|
||||
rO0ABXQAVklmIHlvdSBkZXNlcmlhbGl6ZSBtZSBkb3duLCBJIHNoYWxsIGJlY29tZSBtb3JlIHBvd2VyZnVsIHRoYW4geW91IGNhbiBwb3NzaWJseSBpbWFnaW5l
|
||||
```
|
||||
|
||||
Try to change this serialized object in order to delay the page response for exactly 5 seconds.
|
||||
Try to change this serialized object in order to delay the page response for exactly 5 seconds.
|
||||
|
@ -20,4 +20,4 @@ Many programming languages offer a native capability for serializing objects. Th
|
||||
|
||||
=== Data, not Code
|
||||
|
||||
ONLY data is serialized. Code is not serialized itself. Deserialization creates a new object and copies all the data from the byte stream, in order to obtain and object identical to the object that was serialized.
|
||||
ONLY data is serialized. Code is not serialized itself. Deserialization creates a new object and copies all the data from the byte stream, in order to obtain and object identical to the object that was serialized.
|
||||
|
@ -8,4 +8,4 @@ insecure-deserialization.stringobject=That is not the VulnerableTaskHolder objec
|
||||
|
||||
insecure-deserialization.hints.1=WebGoat probably contains the org.dummy.insecure.framework.VulnerableTaskHolder class as shown on the lesson pages. Use this to construct and serialize your attack.
|
||||
insecure-deserialization.hints.2=The VulnerableTaskHolder might have been updated on the server with a next version number.
|
||||
insecure-deserialization.hints.3=Not all actions are allowed anymore. The readObject has been changed. For serializing it does not effect the data. Follow the additional hints from the feedback on your attempts.
|
||||
insecure-deserialization.hints.3=Not all actions are allowed anymore. The readObject has been changed. For serializing it does not effect the data. Follow the additional hints from the feedback on your attempts.
|
||||
|
@ -1,4 +1,3 @@
|
||||
= Hijack a Session
|
||||
|
||||
In this lesson we are trying to predict the 'hijack_cookie' value. The 'hijack_cookie' is used to differentiate authenticated and anonymous users of WebGoat.
|
||||
|
||||
|
@ -2,9 +2,9 @@
|
||||
|
||||
== Concept
|
||||
|
||||
Application developers who develop their own session IDs frequently forget to incorporate the complexity and randomness necessary for security. If the user specific session ID is not complex and random, then the application is highly susceptible to session-based brute force attacks.
|
||||
Application developers who develop their own session IDs frequently forget to incorporate the complexity and randomness necessary for security. If the user specific session ID is not complex and random, then the application is highly susceptible to session-based brute force attacks.
|
||||
|
||||
|
||||
== Goals
|
||||
|
||||
Gain access to an authenticated session belonging to someone else.
|
||||
Gain access to an authenticated session belonging to someone else.
|
||||
|
@ -30,7 +30,7 @@ Send some clean request (without setting the hijack_cookie) to the /WebGoat/Hija
|
||||
[source, sh]
|
||||
----
|
||||
# command
|
||||
for i in $(seq 1 10); do
|
||||
for i in $(seq 1 10); do
|
||||
curl 'http://localhost:8080/WebGoat/HijackSession/login' \
|
||||
-H 'Connection: keep-alive' \
|
||||
-H 'sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="90"' \
|
||||
|
@ -5,4 +5,4 @@ input and display it back to the user, illustrating the basics of handling an HT
|
||||
== Try It!
|
||||
|
||||
Enter your name in the input field below and press "Go!" to submit. The server will accept the request, reverse the input
|
||||
and display it back to the user, illustrating the basics of handling an HTTP request.
|
||||
and display it back to the user, illustrating the basics of handling an HTTP request.
|
||||
|
@ -1,4 +1,3 @@
|
||||
== The Quiz
|
||||
|
||||
What type of HTTP command did WebGoat use for this lesson. A POST or a GET.
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
= HTTP Basics
|
||||
|
||||
== Concept
|
||||
= HTTP Basics
|
||||
|
||||
== Concept
|
||||
|
||||
This lesson presents the basics for understanding the transfer of data between the browser and the web application and how to trap a request/response with a HTTP proxy.
|
||||
|
||||
== Goals
|
||||
|
||||
The user should become familiar with the features of WebGoat by manipulating the above
|
||||
The user should become familiar with the features of WebGoat by manipulating the above
|
||||
buttons to view hints, show the HTTP request parameters, the HTTP request cookies, and the Java source code. You may also try using
|
||||
link:https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project[OWASP Zed Attack Proxy] for the first time.
|
||||
|
||||
@ -14,9 +14,9 @@ link:https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project[OWASP Zed At
|
||||
|
||||
All HTTP transactions follow the same general format. Each client request and server response has three parts: the request or response line, a header section and the entity body.
|
||||
|
||||
The client initiates a transaction as follows:
|
||||
The client initiates a transaction as follows:
|
||||
|
||||
* The client contacts the server and sends a document request. A GET request can have url parameters and those parameters will be available in the web access logs.
|
||||
* The client contacts the server and sends a document request. A GET request can have url parameters and those parameters will be available in the web access logs.
|
||||
|
||||
** GET /index.html?param=value HTTP/1.0
|
||||
|
||||
@ -25,4 +25,3 @@ The client initiates a transaction as follows:
|
||||
** User-Agent: Mozilla/4.06 Accept: image/gif,image/jpeg, */*
|
||||
|
||||
* In a POST request, the user supplied data will follow the optional headers and is not part of the contained within the POST URL.
|
||||
|
||||
|
@ -49,7 +49,7 @@
|
||||
<!-- using attack-form class on your form will allow your request to be ajaxified and stay within the display framework for webgoat -->
|
||||
<!-- you can write your own custom forms, but standard form submission will take you to your endpoint and outside of the WebGoat framework -->
|
||||
<!-- of course, you can write your own ajax submission /handling in your own javascript if you like -->
|
||||
<form class="attack-form" accept-charset="UNKNOWN"
|
||||
<form class="attack-form" accept-charset="UNKNOWN"
|
||||
method="POST" name="form"
|
||||
action="HttpBasics/attack2">
|
||||
<script>
|
||||
|
@ -13,4 +13,4 @@ http-basics.reversed=The server has reversed your name: {0}
|
||||
|
||||
http-basics.close=Try again: but this time enter a value before hitting go.
|
||||
http-basics.incorrect=You are close, try again: the HTTP Command is incorrect.
|
||||
http-basics.magic=You are close, try again: the magic number is incorrect.
|
||||
http-basics.magic=You are close, try again: the magic number is incorrect.
|
||||
|
@ -13,4 +13,4 @@ http-basics.reversed=De server heeft je naam omgedraaid: {0}
|
||||
|
||||
http-basics.close=Je bent er bijna, probeer nog eens: {0}
|
||||
http-basics.incorrect=het HTTP commando is niet correct.
|
||||
http-basics.magic=het magische getal is niet correct.
|
||||
http-basics.magic=het magische getal is niet correct.
|
||||
|
@ -7,5 +7,3 @@ Otherwise, this will show you how to set up ZAP as a proxy on your local host.
|
||||
* First download and install https://www.zaproxy.org/download/[ZAP] for your operating system
|
||||
* Start ZAP
|
||||
* Start the browser directly from ZAP
|
||||
|
||||
|
||||
|
@ -26,5 +26,3 @@ image::images/zap_edit_and_send.png[Open/Resend with Request Editor,style="lesso
|
||||
++++
|
||||
|
||||
image::images/zap_edit_and_response.png[Open/Resend response,style="lesson-image"]
|
||||
|
||||
|
||||
|
@ -52,5 +52,3 @@ image::images/chrome-manual-proxy.png[Chrome Proxy Config,700,447,style="lesson-
|
||||
image::images/chrome-manual-proxy-win.png[Chrome Proxy, 394,346,style="lesson-image"]
|
||||
|
||||
(Win config image above)
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
2.http-proxies.title=HTTP Proxies
|
||||
|
||||
http-proxies.intercept.success=Well done, you tampered the request as expected
|
||||
http-proxies.intercept.failure=Please try again. Make sure to make all the changes. And case sensitivity may matter ... or not, you never know!
|
||||
http-proxies.intercept.failure=Please try again. Make sure to make all the changes. And case sensitivity may matter ... or not, you never know!
|
||||
|
@ -5,4 +5,4 @@ to perform different functions.
|
||||
|
||||
Use that knowledge to take the same base request, change its method, path and body (payload) to modify another user's (Buffalo Bill's) profile.
|
||||
Change the role to something lower (since higher privilege roles and users are usually lower numbers). Also change the
|
||||
user's color to 'red'.
|
||||
user's color to 'red'.
|
||||
|
@ -1,4 +1,4 @@
|
||||
==== Edit Your Own Profile
|
||||
|
||||
If an application only exposes a way to view your profile or some object (i.e. 'GET' in RESTful), that does not mean you cannot edit it.
|
||||
Use your intercept proxy to modify the request such that it would modify your profile. Change the color from 'yellow' to 'black' (sans single quotes).
|
||||
Use your intercept proxy to modify the request such that it would modify your profile. Change the color from 'yellow' to 'black' (sans single quotes).
|
||||
|
@ -1 +1 @@
|
||||
Please input the alternate path to the Url to view your own profile. Please start with 'WebGoat' (i.e. disregard 'http://localhost:8080/')
|
||||
Please input the alternate path to the Url to view your own profile. Please start with 'WebGoat' (i.e. disregard 'http://localhost:8080/')
|
||||
|
@ -4,4 +4,4 @@ Many access control issues are susceptible to attack from an authenticated-but-u
|
||||
|
||||
The id and password for the account in this case are 'tom' and 'cat' (It is an insecure app, right?).
|
||||
|
||||
After authenticating, proceed to the next screen.
|
||||
After authenticating, proceed to the next screen.
|
||||
|
@ -4,4 +4,4 @@
|
||||
|
||||
View someone else's profile by using the alternate path you already used to view your own profile. Use the 'View Profile' button
|
||||
and intercept/modify the request to view another profile. Alternatively, you may also just be able to use a manual GET request with
|
||||
your browser.
|
||||
your browser.
|
||||
|
@ -4,4 +4,4 @@
|
||||
|
||||
The application we are working with seems to follow a RESTful pattern so far as the profile goes. Many apps have roles in which an elevated user may access content of another.
|
||||
In that case, just /profile won't work since the own user's session/authentication data won't tell us whose profile they want view.
|
||||
So, what do you think is a likely pattern to view your own profile explicitly using a direct object reference?
|
||||
So, what do you think is a likely pattern to view your own profile explicitly using a direct object reference?
|
||||
|
@ -43,4 +43,4 @@ idor.view.own.profile.failure1=Please try again. The alternate route is very sim
|
||||
idor.view.own.profile.failure2=You need to authenticate as tom first.
|
||||
|
||||
idor.view.other.profile.failure1=You must authenticate first
|
||||
idor.view.other.profile.failure2=<<still working>>
|
||||
idor.view.other.profile.failure2=<<still working>>
|
||||
|
@ -3,4 +3,4 @@ function submit_secret_credentials() {
|
||||
xhttp['open']('POST', 'InsecureLogin/login', true);
|
||||
//sending the request is obfuscated, to descourage js reading
|
||||
var _0xb7f9=["\x43\x61\x70\x74\x61\x69\x6E\x4A\x61\x63\x6B","\x42\x6C\x61\x63\x6B\x50\x65\x61\x72\x6C","\x73\x74\x72\x69\x6E\x67\x69\x66\x79","\x73\x65\x6E\x64"];xhttp[_0xb7f9[3]](JSON[_0xb7f9[2]]({username:_0xb7f9[0],password:_0xb7f9[1]}))
|
||||
}
|
||||
}
|
||||
|
@ -113,4 +113,4 @@ a.list-group-item.active small {
|
||||
|
||||
.meta a:hover {
|
||||
color: rgba(0, 0, 0, .87);
|
||||
}
|
||||
}
|
||||
|
@ -56,4 +56,3 @@ Instead, use static keys that are securely managed and updated regularly.
|
||||
- **Audit and monitoring**: Regularly audit JWT usage, monitor for suspicious activity, and implement anomaly detection mechanisms.
|
||||
|
||||
- **Security testing**: Regularly perform security testing, including penetration testing and code reviews, to identify and remediate potential vulnerabilities.
|
||||
|
||||
|
@ -3,4 +3,3 @@
|
||||
Below you see two accounts, one of Jerry and one of Tom.
|
||||
Jerry wants to remove Tom's account from Twitter, but his token can only delete his account.
|
||||
Can you try to help him and delete Toms account?
|
||||
|
||||
|
@ -9,4 +9,3 @@ eyJhbGciOiJIUzI1NiJ9.ew0KICAiYXV0aG9yaXRpZXMiIDogWyAiUk9MRV9BRE1JTiIsICJST0xFX1V
|
||||
----
|
||||
|
||||
Copy and paste the following token and decode the token, can you find the user inside the token?
|
||||
|
||||
|
@ -58,4 +58,3 @@ try {
|
||||
----
|
||||
|
||||
Can you spot the weakness?
|
||||
|
||||
|
@ -43,4 +43,4 @@ One of the drawbacks of using this method is that JWT is widely spread for examp
|
||||
|
||||
For more information take a look at the following video:
|
||||
|
||||
video::RijGNytjbOI[youtube, height=480, width=100%]
|
||||
video::RijGNytjbOI[youtube, height=480, width=100%]
|
||||
|
@ -16,4 +16,3 @@ information in the token to identify the user.
|
||||
|
||||
The token contains claims to identify the user and all other information necessary for the server to fulfill the request.
|
||||
Be aware not to store sensitive information in the token and always send it over a secure channel.
|
||||
|
||||
|
@ -6,4 +6,4 @@ Some best practices when working with JWT:
|
||||
- Make sure you use an appropriate key length when using a symmetric key for signing the token.
|
||||
- Make sure the claims added to the token do not contain personal information. If you need to add more information opt for encrypting the token as well.
|
||||
- Add sufficient test cases to your project to verify invalid tokens actually do not work. Integration with a third party to check your token does not mean you do not have test your application at all.
|
||||
- Take a look at the best practices mentioned in https://tools.ietf.org/html/rfc8725#section-2
|
||||
- Take a look at the best practices mentioned in https://tools.ietf.org/html/rfc8725#section-2
|
||||
|
@ -1,6 +1,6 @@
|
||||
= JWT Tokens
|
||||
|
||||
== Concept
|
||||
|
||||
== Concept
|
||||
|
||||
This lesson teaches about using JSON Web Tokens (JWT) for authentication and the common pitfalls you need to be aware of
|
||||
when using JWT.
|
||||
@ -34,7 +34,3 @@ the validity and integrity of the token in a secure way, all of this in a statel
|
||||
and portable approach (portable in the way that client and server technologies can
|
||||
be different including also the transport channel even if HTTP is the most often used)
|
||||
-------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -85,4 +85,3 @@ application you are better of using plain old cookies. See for more information:
|
||||
- http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/[stop-using-jwt-for-sessions, window="_blank"]
|
||||
- http://cryto.net/~joepie91/blog/2016/06/19/stop-using-jwt-for-sessions-part-2-why-your-solution-doesnt-work/[stop-using-jwt-for-sessions-part-2-why-your-solution-doesnt-work, window="_blank"]
|
||||
- http://cryto.net/~joepie91/blog/attachments/jwt-flowchart.png[flowchart, window="_blank"]
|
||||
|
||||
|
@ -9,5 +9,3 @@ found in a private bug bounty program on Bugcrowd, you can read the full write u
|
||||
|
||||
From a breach of last year the following logfile is available link:images/logs.txt[here]
|
||||
Can you find a way to order the books but let *Tom* pay for them?
|
||||
|
||||
|
||||
|
@ -14,7 +14,3 @@ to be aware of before validating the token.
|
||||
== Assignment
|
||||
|
||||
Try to change the token you receive and become an admin user by changing the token and once you are admin reset the votes
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -86,6 +86,3 @@ Now we can replace the token in the cookie and perform the reset again. One thin
|
||||
For more information take a look at the following video:
|
||||
|
||||
video::wt3UixCiPfo[youtube, height=480, width=100%]
|
||||
|
||||
|
||||
|
||||
|
@ -32,4 +32,4 @@ information about how this attack works.
|
||||
The best recommendation is to choose for the cookie based approach. In practise it is easier to defend against a CSRF
|
||||
attack. On the other hand many JavaScript frameworks are protecting the user for a XSS attack by applying the right
|
||||
encoding, this protection comes out of the box. A CSRF protection sometimes is not provided by default and requires work.
|
||||
In the end take a look at what the framework is offering you, but most of the time a XSS attack gives the attacker more leverage.
|
||||
In the end take a look at what the framework is offering you, but most of the time a XSS attack gives the attacker more leverage.
|
||||
|
@ -13,5 +13,3 @@ The token is base64 encoded and consists of three parts:
|
||||
|
||||
Both header and claims consist are represented by a JSON object. The header describes the cryptographic operations applied to the JWT and optionally, additional properties of the JWT.
|
||||
The claims represent a JSON object whose members are the claims conveyed by the JWT.
|
||||
|
||||
|
||||
|
@ -7,4 +7,3 @@ dictionary attack is not feasible. Once you have a token you can start an offlin
|
||||
=== Assignment
|
||||
|
||||
Given we have the following token try to find out secret key and submit a new key with the username changed to WebGoat.
|
||||
|
||||
|
@ -6,7 +6,7 @@ jwt-invalid-token=Not a valid JWT token, please try again
|
||||
jwt-only-admin=Only an admin user can reset the votes
|
||||
jwt-change-token-hint1=Select a different user and look at the token you receive back, use the delete button to reset the votes count
|
||||
jwt-change-token-hint2=Decode the token and look at the contents
|
||||
jwt-change-token-hint3=Change the contents of the token and replace the cookie before sending the request for getting the votes
|
||||
jwt-change-token-hint3=Change the contents of the token and replace the cookie before sending the request for getting the votes
|
||||
jwt-change-token-hint4=Change the admin field to true in the token
|
||||
jwt-change-token-hint5=Submit the token by changing the algorithm to None and remove the signature
|
||||
|
||||
@ -23,7 +23,7 @@ jwt-refresh-hint4=Use the found access token in the Authorization: Bearer header
|
||||
jwt-refresh-not-tom=User is not Tom but {0}, please try again
|
||||
jwt-refresh-alg-none=Nicely found! You solved the assignment with 'alg: none' can you also solve it by using the refresh token?
|
||||
|
||||
jwt-final-jerry-account=Yikes, you are removing Jerry's account, try to delete the account of Tom
|
||||
jwt-final-jerry-account=Yikes, you are removing Jerry's account, try to delete the account of Tom
|
||||
jwt-final-not-tom=Username is not Tom try to pass a token for Tom
|
||||
|
||||
jwt-jku-hint1=Take a look at the token and specifically and the header
|
||||
|
@ -31,6 +31,3 @@ function updateTotal() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -6,4 +6,3 @@ function follow(user) {
|
||||
$("#toast").append(result);
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -39,4 +39,4 @@ function newToken() {
|
||||
localStorage.setItem('refresh_token', refreshToken);
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -84,4 +84,3 @@ function vote(title) {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,4 +2,4 @@ $(document).ready(
|
||||
function(){
|
||||
$("#secrettoken").load('JWT/secret/gettoken');
|
||||
}
|
||||
);
|
||||
);
|
||||
|
@ -17,4 +17,4 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -6,4 +6,3 @@ This lesson describes the steps needed to add a new lesson to WebGoat. In genera
|
||||
- Add one or more assignments within the lesson
|
||||
|
||||
Let's see how to create a new lesson.
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user