how to encrypt password text input using script mode in Katalon ? - groovy

I have a csv with a list of users and passwords that I need check the login.
Is there any way to encrypt password text input using script mode in
Katalon ?
I found an answer on katalon forums but they do that manually using a a tool of the IDE like you can see here Working with Sensitive Text
I would like to create an script that for every (user,password) encrypt the password and login using encrypted password.
#Keyword
def login(user, password, url){
WebUI.navigateToUrl(url)
WebUI.setText(findTestObject('Object Repository/Page_Sign in My Page/input_SigninFormemail'),user)
def password_encript = Encrypt(password)// Fictitious method that I would like to get
WebUI.setEncryptedText(findTestObject('Object Repository/Page_Sign in My Page/input_SigninFormpassword'), password_encript)
WebUI.click(findTestObject('Object Repository/Page_Sign in My Page/input_yt0'))
}
Is there a method like Encrypt(password) in Katalon?
Is there a way to do that in code?
Thanks in advance.

I came across this question while investigating other Katalon encryption questions, and thought I may offer some late insight.
The "setEncryptedText(TestObject, encryptedText)" method is to allow you to store sensitive text in an encrypted form, which is then decrypted when entered into the web application.
Since your method is being passed 'password' as a string in cleartext, then why not just have the function do:
WebUI.setText(findTestObject('Object Repository/Page_Sign in My Page/input_SigninFormpassword'), password)

So to use Java Encryption : Blowfish with Text and Key.
Here is my solution :
public static String encrypt(String strClearText,String strKey) throws Exception{
String strData="";
// streData - here you put your data
try {
SecretKeySpec skeyspec=new SecretKeySpec(strKey.getBytes(),"Blowfish");
Cipher cipher=Cipher.getInstance("Blowfish");
cipher.init(Cipher.ENCRYPT_MODE, skeyspec);
byte[] encrypted=cipher.doFinal(strClearText.getBytes());
strData=new String(encrypted);
} catch (Exception e) {
e.printStackTrace();
throw new Exception(e);
}
return strData;
}

Related

Fetching OpenIdConnectConfiguration while offline/no connection to AuthServer

I've been working on how to save OpenIdConnecConfiguration locally in the odd case that the AuthServer is not reachable but the frontend client (e.g. Phone) still has a valid refresh token which still needs to be validated again when signing in. It is also needed to be saved locally to a file in the case that the backend (e.g. WCF) has restarted due to a update or the frequent restarts it has (once a day)
What I've done so far, I've saved the JSON object of the ".well-known/openid-configuration" to a file/variable and now I want to create the OpenIdConnectConfiguration object.
OpenIdConnectConfiguration.Create(json) does a lot of the work but the signingKeys do not get created. I think maybe it's because the authorization endpoint needs to be created in some other manner maybe?
Or maybe I'm doing this the wrong way and there is another solution to this issue. I'm working in C#.
Edit: I know there are some caveats to what I'm doing. I need to check once in awhile to see if the public key has been changed, but security wise it should be fine to save the configuration because it's already public. I only need the public key to validate/sign the jwt I get from the user and nothing more.
Figured out a solution after looking through OpenIdConnectConfiguration.cs on the official github.
When fetching the OpenIdConnectConfiguration the first time, use Write() to get a JSON string and use it to save it to file.
Afterwards when loading the file, use Create() to create the OpenIdConnectConfiguration again from the JSON string (This had the issue of not saving the signingKeys as said in the question, but alas! there is a fix)
Lastly to fix the issue with the signingKeys not being created, (this is what I found out from the github class) all we need to do is loop through the JsonWebKeySet and create them as is done in the class. We already have all the information needed from the initial load and therefore only need to create them again.
I'll leave the code example below of what I did. I still need to handle checking if he key has been changed/expired which is the next step I'll be tackling.
interface IValidationPersistence
{
void SaveOpenIdConnectConfiguration(OpenIdConnectConfiguration openIdConfig);
OpenIdConnectConfiguration LoadOpenIdConnectionConfiguration();
}
class ValidationPersistence : IValidationPersistence
{
private readonly string _windowsTempPath = Path.GetTempPath();
private readonly string _fileName = "TestFileName";
private readonly string _fullFilePath;
public ValidationPersistence()
{
_fullFilePath = _windowsTempPath + _fileName;
}
public OpenIdConnectConfiguration LoadOpenIdConnectionConfiguration()
{
FileService fileService = new FileService();
OpenIdConnectConfiguration openIdConfig = OpenIdConnectConfiguration.Create(fileService.LoadFromJSONFile<string>(_fullFilePath));
foreach (SecurityKey key in openIdConfig.JsonWebKeySet.GetSigningKeys())
{
openIdConfig.SigningKeys.Add(key);
}
return openIdConfig;
}
public void SaveOpenIdConnectConfiguration(OpenIdConnectConfiguration openIdConfig)
{
FileService fileService = new FileService();
fileService.WriteToJSONFile(OpenIdConnectConfiguration.Write(openIdConfig), _fullFilePath);
}
}

preprocess csv files to convert key values to lowercase when using Hybris hotfolder

CSV files are having data in uppercase for keys like UID, is there a way to convert UID to lowercase and save when using hot folder in hybris. A change on our data source will take more time than hybris change.
I am thinking of creating a LowerCaseValueTranslator for impex. is it a good approach?
I have explored LowerCaseValueTranslator path.
#Override
public Object importValue(final String valueExpr, final Item toItem) throws JaloInvalidParameterException
{
clearStatus();
Double result = null;
if (!StringUtils.isBlank(valueExpr))
{
try
{
result = valueExpr.toLowerCase();
}
catch (final NumberFormatException exc)
{
setError();
}
}
return result;
}
}
I expect that it will work - is this the best approach to do this
Is the data/UID autogenerated by Hybris, or is it a custom value from user?
In any case, a translator is a good approach to do what you want (assuming the data is a custom value). If it is autogenerated by Hybris, I would keep it as-is.

List of keys that should most probably be removed from log files?

Recently I noticed some sensitive data was being written out to a log file in an app I'm working on. I looked into it, and our app has a list of keys that it will remove from our logs before writing them out, but the list feels to me like it could be expanded.
Is there a list somewhere of common keys that should be removed from log files when found?
For example the following keys and their variations should probably never be logged anywhere in a log file
access_token
auth_token
client_id
client_secret
oauthSecret
oauthToken
password
refresh_token
connection_string
Note that I've seen the OWASP Logging cheat sheet, but it didn't seem to have any specifics in it, just generalizations.
So far the best I've been able to come up with is the following, and I found my best results by searching for "redact secret password token" in Google.
Redact keys that have the following anywhere in their name
remembering that keys can show up in any of the following ways: x=y, x:y, 'x':y, "x":y <x>y</x>
token
secret
password
session
connection
jwt
consider removing all username variations as well, like:
username
user_name
user
email
credential
Redact values that look like
credit card numbers
social insurance numbers
possibly email addresses
Cloudera has a page detailing regular expressions for redacting some data values, not keys:
Credit Card numbers (with separator)
\d{4}[^\w]\d{4}[^\w]\d{4}[^\w]\d{4}
Social Security numbers (with separator) \d{3}[^\w]\d{2}[^\w]\d{4}
Email addresses \b([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-._] \
[A-Za-z0-9])#(([A-Za-z0-9]|[A-Za-z] \ [A-Za-z0-9-][A-Za-z0-9]).)+([A-Za-z0-9] \
|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9])\b
Hostnames \b(([A-Za-z]|[A-Za-z][A-Za-z0-9-] \
[A-Za-z0-9]).)+([A-Za-z0-9] \ |[A-Za-z0-9][A-Za-z0-9-][A-Za-z0-9])\b
Node module for redacting data
https://github.com/watson/redact-secrets
Note: A coworker of mine did a great job of supplying me with a java sample of key value redacting in Java, using a regex to eliminate key values that contain `session,secret,token,password,passwd,connection' in xml and json, and quoted variants.
import java.security.GeneralSecurityException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Redact {
private static final String prefix = "[\"']?(session|(auth_)?token|password|passwd|secret|connection)[\"']?";
private static final String capture = "([\"']?)([\\w\\d!#$%()*+,-./:<=>?#[\\\\]^_`{|}~]+)([\"']?)";
private static Pattern pattern = Pattern.compile(prefix + "\\s*(=|:)\\s*" + capture, Pattern.CASE_INSENSITIVE);
public static String encryptSensitiveInfo(String message) {
try {
if (message == null)
return message;
StringBuffer newStr = new StringBuffer(message);
int lenDiff = 0;
Matcher m = pattern.matcher(message);
// Loop over message until all sensitive data is redacted
while (m.find()) {
String keyAndValue = m.group(0);
String value = m.group(5);
String REDACTED = "REDACTED";
String replacementText = keyAndValue.replace(value, REDACTED);
// Replace the key/value in the message with the new redacted
// value, adjusting for where it is in the redacted version of
// the input
newStr = newStr.replace(m.start() - lenDiff, m.end() - lenDiff, replacementText);
lenDiff += keyAndValue.length() - replacementText.length();
}
return newStr.toString();
} catch (Exception e) {
return message;
}
}
}

Searching in JavaMail - how to make it happen server side?

I think I'm missing something about how to search in JavaMail.
Download empty messages from a folder
Create a new SearchTerm that matches your results
Filter (yourFolder.search) the results using your search term.
This works. But - why do it this way? If I'm using javamail to connect to something like gmail, the search isn't being executed server-side, and it doesn't seem like there is any advantage to using the whole javax.mail.search.SearchTerm constructs in terms of efficiency or reducing the amount of data that needs to be sent over the network...
I don't see any way that executes a search on the server side and returns a list of matches. Any ideas?
EDIT: Including pseudocode of what I'm doing now, which doesn't execute any search on the server-side. Even if I converted this to use SearchTerm it still wouldn't be doing anything server-side, right?
Properties props = System.getProperties();
props.setProperty("mail.store.protocol", "gimaps");
final Session session = Session.getDefaultInstance(props, null);
final GmailSSLStore store = (GmailSSLStore) session.getStore("gimaps");
store.connect(ADDRESS, PASSWORD);
final GmailFolder allMailFolder = (GmailFolder) store.getFolder("[Gmail]/All Mail");
allMailFolder.open(Folder.READ_ONLY);
final Message[] allMessages = allMailFolder.getMessages();
System.out.println("Messages:" + allMessages.length);
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.ENVELOPE);
allMailFolder.fetch(allMessages, fp);
for (final Message message : allMessages) {
final Address[] addrs = message.getFrom();
if (addrs != null) {
for (final Address addr : addrs) {
if (addr.toString().toLowerCase().contains("george")) {
System.out.println(addr.toString());
}
}
}
}
You're doing something wrong, but you haven't provided enough details about what you're doing for us to know what you're doing wrong.
Are you using IMAP?
Show us some code and the debug output.
If you're searching in an IMAP folder using the predefined SearchTerm implementations, it will try to perform the search on the server. Look at the implementation of SearchSequence.generateSequence. In your example you would probably want to use FromStringTerm.
If you're using the gimap provider, you can also use Google's IMAP extensions, which include the X-GM-RAW search attribute, allowing you to search exactly like in the Gmail web interface. The java implementation is in GmailRawSearchTerm and only works server-side.

Noob way to login the user in Prestashop

This is a walkthrough on how to make a user login on prestashop without passing through the login screen. This is helpful if you do not want the user to login again like when you want to transfer his session from one website to prestashop.
Step 1 Eliminate the need for password salting. Under config/settings.inc.php, set _COOKIE_KEY_ to blank. Note this also means that you must create a new customer. Or you can delete the old md5 password from DB and add your own.
Step 2 In the authentication.php file paste the following lines after line 6:
$customer = new Customer();
//$authentication = $customer->getByEmail(trim($email), trim($passwd));
$authentication = $customer->getByMd5(trim($email), trim($passwd)); //modified version of getByEmail if we are not accepting $passwd in cleartext but in md5.
/* Handle brute force attacks */
sleep(1);
if (!$authentication OR !$customer->id)
$errors[] = Tools::displayError('authentication failed');
else
{
$cookie->id_customer = intval($customer->id);
$cookie->customer_lastname = $customer->lastname;
$cookie->customer_firstname = $customer->firstname;
$cookie->logged = 1;
$cookie->passwd = $customer->passwd;
$cookie->email = $customer->email;
if (Configuration::get('PS_CART_FOLLOWING') AND (empty($cookie->id_cart) OR Cart::getNbProducts($cookie->id_cart) == 0))
$cookie->id_cart = intval(Cart::lastNoneOrderedCart(intval($customer->id)));
Module::hookExec('authentication');
if ($back = Tools::getValue('back'))
Tools::redirect($back);
//Tools::redirect('my-account.php'); //cut redirection to break infinite loop
}
The above code is what makes the user login using $email as username and $passwd as password in plaintext. The original code comes from the if (Tools::isSubmit('SubmitLogin')) function inside the authentication.php file.
Step 3 Paste the above code in the products.php file just under line 5
Step 4 In case you are sending $passwd directly in md5 format, here is the modified version of getByEmail()(customer.php):
public function getByMd5($email, $passwd = NULL)
{
$result = Db::getInstance()->GetRow('SELECT * FROM `'._DB_PREFIX_ .'customer` WHERE `active` = 1 AND `email` = \''.pSQL($email).'\' '.(isset($passwd) ? 'AND `passwd` = \''.pSQL(_COOKIE_KEY_.$passwd).'\'' : '').' AND `deleted` = 0');
if (!$result)
return false;
$this->id = $result['id_customer'];
foreach ($result AS $key => $value)
if (key_exists($key, $this))
$this->{$key} = $value;
return $this;
}
You can get access to the username/passwd either through the $_COOKIE[] function or through $_GET[]. Either way its a big security risk. Cookie reading can be placed in the index.php file.
This approach you have proposed is extremely insecure. A salt is required for password safety and should never be removed. Further more by authenticating a user with their MD5 hash you effectively voiding all protection that hashing passwords provides you. People hash passwords because attacks like SQL injection allow an attacker to obtain this hash which then needs to be cracked. In this scenario the attacker can grab the admin's hash and just login right away.
The correct way to do session sharing:
Create a simple table to store session state. In this case the Cryptgoraphic Nonce is a large random value used to reference the data.
'insert into session_state (sess,token) value ('.pSQL(serialize($_SESSION)).', '.$cryptographic_nonce.')'
When the browser is redirected to another shop give them a redirect like this:
header('location: https://some_other_shop/landing.php?token=$cryptographic_nonce');
When the new server gets this landing request it fetches the session state from the previous server:
$sess=http_get($_SERVER['HTTP_REFERER']."?token=$_GET[token]");
$_SESSION=unserialize($sess);
Note you might have to transfer the user's data in the database as well.

Resources