Wednesday, January 8, 2020

Major Vulnerabilities and Security Issues in AEM

Hello Everyone,

While working with AEM, There are many security concerns which we need to take care at Apache level to stop the attacker by attacking the website.
There are few security Headers which are required to provide security in the Apache level.

1. X-XSS Protection: X-XSS-Protection header can prevent some level of XSS (cross-site-scripting) attacks.
<IfModule mod_headers.c>
<FilesMatch "\.(htm|html)$">
                        #Force XSS (should be on by default in most browsers anyway)
                        Header always set X-XSS-Protection "1; mode=block"

There are four possible ways you can configure this header.
0: XSS filter disabled 1: XSS filter enabled and sanitized the page if attack detected 1;mode=block XSS filter enabled and prevented rendering the page if attack detected 1;report= XSS filter enabled and reported the violation if attack detected
Note:We will use 1:mode=block to implement this security.This need to be put in publish.vhost files for every domain.

2. HTTP Strict Transport Security:HSTS (HTTP Strict Transport Security) header to ensure all communication from a browser is sent over HTTPS (HTTP Secure). This prevents HTTPS click through prompts and redirects HTTP requests to HTTPS.Before implementing this header, you must ensure all your website page is accessible over HTTPS else they will be blocked.
Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains;"

Note: AMS Users can just uncomment it base_rewrite_rules file.Enable it only if the server is on HTTPS.

3. X-Frame-Options: Use the X-Frame-Options header to prevent Clickjacking vulnerability on your website. By implementing this header, you instruct the browser not to embed your web page in frame/iframe.
<IfModule mod_headers.c>
         Header merge X-Frame-Options SAMEORIGIN
Note: Put X-XSS Protection and X-Frame-Options in <IfModule mod_headers.c>.

4. Content Security Policy: Prevent XSS, clickjacking, code injection attacks by implementing the Content Security Policy (CSP) header in your web page HTTP response.The idea of this is that you can define all the third party domains from where you want to load anything on your website. So if attacker inject anything from and this domain is not in the list of content security policy, then those requests will not load on a page and you can see exceptions in the console.

In the below example, you need to use your website domain in place of
Header always set content-security-policy "script-src blob: data: 'unsafe-inline'
'unsafe-eval' 'self'"

Note: To implement this security, if anytime you want to load and use any third party libraries, you always need to add the domain in this configuration.

Hope it will help you guys !!
Thanks and Happy Learning.

Sunday, January 5, 2020

Handing 301 Redirection in AEM using Redirect Map Manager

Hello Everyone,

In one of my previous blog, I explained about 301 Redirection and how to manage 301 redirects in AEM via page properties.

Ideally when we need 301 redirection?
1. When you are completely changing the website with a new hierarchy of Pages and Assets, 301 redirection is needed.The idea is the old users who were using the website will never get 404 and still can be redirected to the correct place.
2. If you want 301 redirection of  internal URL’s to External Sites.

Does the approach of 301 Redirection via page properties really solve the issue if not
then why?
1. Let's suppose we have a old website /content/we-retail/en/home.html and now the new home page is /content/we-retail/home.html, we won't manage the old hierarchy in our AEM, then having 301 redirection in page properties won’t really help.

2. The page properties 301 can only work, if you have a page just to create the hierarchy but you always want user to redirect to some other place.For instance: you have a page /content/we-retail/en and you want to 301 redirect to this page to home page.

Conclusion: Having 301 redirection in page properties can not solve all the use cases of 301 redirection.

If we are managing single/multiple websites in AEM, we really want a full fledged solution to
handle 301 redirection.
ACS Commons Redirect Map Manager is really able to solve all the above mentioned
issues And we can manage all the 301 redirection at the Apache level itself.

How to configure Redirect Map Manager for your project in AEM.
1. Go to miscadmin console. Go to Tools->acs commons->Redirect Maps.
2. Create a new Page.
Fig1: Create a page for Redirect Maps
3. Enter the Title/Name of your redirect map and click Create.
4.Upload a Redirect Map base file (optional). This can be useful for specifying miscellaneous or external redirects which aren’t found for pages in the AEM repository. For example, redirecting a particular URL to an external application.
5. If you don't want to upload a file, Go to "Edit entries" Tab and “Add Entry” by entering Source and Target. Use source as relative path and target you can configure the relative path if you want 301 redirection at the same domain or can configure the full external domain to redirect.
Fig2: Add entries for 301 Redirection
6. You can preview the list of all 301 redirection.In the “Download Preview”, you got the URL through which Apache server can access this file from AEM.
Fig3: Preview will show the link to access redirect map.
7. Publish the Redirect Map Pages.

Handling Configuration in Apache
1. Add a bash script (redirect-map.txt) to pull the redirect Map file from publisher.You can put it anywhere but i placed it in “/etc/httpd/conf.d/redirects/redirect-map.txt”. [The extension of the script can be .sh or .txt]

Below is the explanation of bash script line by line.
line No 4: need to change with the publish private IP to which apache should able to connect.(Can be tested via telnet)
line No 5:Need to define the log directory of the apache server
line No 7:This is the name of the redirect map you created in your AEM. If there are multiple redirect map to handle multiple sites, you can add all the redirect Map pages name here.
line No 12: This line will start loop for all the map files one by one.Let’s see the execution of we-retail map file.
line No 15: Will remove the file from /tmp/we-retail.txt 
line no 16:It will fetch the file from the publisher and put it in “/tmp/we-retail” and log this activity in a log file named “update-redirect-map.log”.
line No 17: convert the /tmp/we-retail file to a DBM file and place the newly db files(.pag file and dir file) in conf directory. So the files gets created are /conf/httpd/conf/tmp-we-retail.pag and /etc/httpd/conf/tmp-we-retail.dir and log this activity in log file.
line No 18,Move the file from /etc/httpd/conf/tmp-we-retail.dir to /etc/httpd/conf/we-retail.dir
line No 19,Move the file from /etc/httpd/conf/tmp-we-retail.pag to /etc/httpd/conf/we-retail.pag
From Line 12 to Line 19 will execute for geometrixx also and for all the websites you will define in the above script.

2.Add a rewrite rule in the /etc/conf.d/rewrites/we_retail_base_rewrites.rules
# Rewrite rules
RewriteMap map.legacy dbm:/etc/httpd/conf/
RewriteCond ${map.legacy:$1} !=""
RewriteRule ^(.*)$      ${map.legacy:$1|/} [L,R=301]
If you are managing multiple sites, in every domain redirect.rules file you need to change the /etc/httpd/conf/ file to the corresponding domain map file.

3. How to set cron expression to execute the above script on an hourly basis.
To open the cron file run the command:
sudo crontab -e
sudo /bin/crontab -e
A file gets opened and you can add your cron expression like shown below.I have set the cron expression on hourly basis. 
0 * * * * sh /etc/httpd/conf.d/redirects/redirect-map.txt  2>&1 /var/log/httpd/map-update-cron.log

Fig: Screenshot for the cron expression in apache

When you do all the configuration, you need to manually run the bash script one time by running the command “sh redirect-map.txt”

Because the rewrite rule try to fetch map file which doesn’t gets created by then, may be your cron job will create it in an hour. So run one time manually to restart the Apache server and later cron job can take care of this activity on an interval.

Vanity URL Issue: As you know that vanity URL’s can not be duplicated within the whole AEM. AEM can only have one unique vanity and in the case of Multiple sites, we may have requirements of having the same vanity for two domains. In this case also in place of vanity, you can manage this in 301 redirect map file for both domains and as every website map file is different so there won't be any conflict.

Limitations of 301 Redirects in Redirect Map Manager:
301 Redirect Map is really a cool feature but it has some limitations.
1. This is one to one mapping and we can not manage a regex here. So if we have 1000 of URL’s need to redirect in a particular pattern you can not manage in Redirect Map. For this, you have to manage it in Apache level.So create a file and add all the regex redirect URL’s like shown below.
RewriteRule ^/en/index(.*)html$  /en/home.html [R=301,L]
Include the file in the rewrite file of a particular website.

Note: All the directories I mentioned above are as per AMS Servers directory structure.
If you have different folder structure you can manage as per your need.

Note: Redirect Map Manager is not an AEM Feature but an ACS Commons feature.
So you need to install ACS Commons package in your AEM Server.

Note: When you made any change in Apache configuration, don’t directly restart.
Run a command “httpd-t” to check all the syntax first. If “Syntax Ok” then
only restart otherwise the Apache will go down if the syntax is not OK.

shivani@dispatcher2apsoutheast1:~ httpd -t
Syntax OK

Conclusion and Benefits of Using Redirect Map Manager

1. If you are managing 301 redirects like this, you don't need to manage 301 redirects at the page properties level. If there is any page in AEM, which you want to redirect just configure the page in the redirect Map Manager.

2. Through this approach you can give an author the privilege that if they miss out any 301 redirection, they can do it anytime they want.
3. If there are many vanity URL’s and because so many vanity URL’s impact the performance of the server, you can use 301 redirection in place of vanities.
4. You can use same vanities for different domains sharing the same AEM Server.

Hope it will help you guys !!
Thanks and Happy Learning.

Saturday, January 4, 2020

How to manage certificates in AEM Truststore

Hello Everyone,

In this blog, we will talk about what is Truststore, how to manage certificates in AEM
Truststore and challenges we face while managing the certificates in publish server.

What is Truststore: TrustStore is used in context of setting up SSL connection in Java application between
client and server.  In SSL handshake, purpose of trustStore is to verify credentials.
The public key certificates provided by CA authorities for encrypting the content are
also be stored in the TrustStore.
TrustStore stores public key or certificates from CA (Certificate Authorities) which is
used to trust remote party or SSL connection.

How to manage these certificates in AEM and how to fetch the public key from
that certificate in your AEM Code.
1.Go to AEM-> Tools->Security->TrustStore.
2. Go to Add Certificates from CER File Section and Select Certificate File to Upload and click on Submit.
Fig1: AEM Truststore Console to Upload Certificates
3. Every certificate will generate a unique Alias Name(certalias___1577961678433 for the above certificate).
The above uploaded certificates gets stored in "/etc/truststore" in CRX:
Fig2: Certificates get Stored in CRX

How to fetch the public key from the certificate using Alias Name:

Note: To fetch the certificate public key from alias, you must have an OSGI config for Alias.Ideally you should upload all certificates in author and replicate /etc/truststore path to all the publishers to maintain same alias for all the servers sitting on the same environment.
If we upload certificates in publishers without replication, the publisher may generate different alias Id and if two publishers of same environment generate different alias then to maintain the different OSGi configurations for both publishers is not possible.So always upload in author and replicate it all the publishers.

Note:If you have few certificates in author and some of them you don’t want in publish server, in AEM there is no way that you can replicate only one certificate but not another but if you really don't want some certificates in publish, then you replicate first all certificates and go to publish server and delete the unwanted one .[Recommended by adobe]

Note: Don’t ever pass the anonymous resourceResolver in KeyStoreService API because to access the certificates in publish, you need to give /etc/truststore an anonymous access and you should be very aware about anonymous access in publish servers. So always get resourceResolver from System User. There is an OOTB Service user named “truststore-reader-service” available for fetching the trustore values in publish server.

Hope it will help you guys !!
Thanks and Happy Learning.

Sunday, December 29, 2019

CryptoSupport in AEM 6.5

Hello Everyone,

While working with AEM, The information related to an API like endpoint,username and
password  used to be maintained in OSGi Configurations.

Sometimes these API’s are really secure and the client don’t want the password to be seen
by anyone. OSGi Configurations are always part of the code.Even in some cases, clients
don’t want to share the password even with developer, they want to use an encryption methodology so that they can share the encrypted code with the developer and the code can be decrypted only at run time and nobody can not know about it.

AEM provides us that kind of cryptosupport which can really make things really confidential
and secure.
  • There is Crypto console in AEM, through which clients can generate the encryption code without even sharing the plain text with the developer.
  • They can just share the encryption key and developer can put it in codebase as OSGi Configuration. There is no console in AEM, from where the encrypted code can be decrypted into plain text.
  • Every instance hmac/master key is different and if the developer knows the encrypted key they can’t get to know the plain text by any way.In other words, the encrypted key will be unique for each and every servers.

So how to use CryptoSupport in AEM?
1.Go to Crypto Support using felix console in AEM and type your password/any sensitive information in plain text field and click on Protect to encrypt this.
2.The code to decrypt the key is below:

CryptoSupport cryptosupport;

Public getDecryptedKey(int encryptedKey)
Now the major concern of using this encryption method come up with production servers. As i mentioned previously that every instance is unique and generate a different encrypted key. But ideally the production server might have two publishers and we can't create configuration based on individual publisher. So the ideal scenario is, we want to use the same key for all authors and publishers belong to one environment.

So ideally all the servers related to one environment irrespective of author/publishers must be sharing the same key.

How to do that?
Before AEM 6.2, you can see the “hmac” and master files directly in AEM CRX, but due to security concerns, these keys have been removed from crx and moved inside the bundle.
1. Go to the author instance and see the bundle id of “Adobe Granite Crypto Bundle Key Provider (com.adobe.granite.crypto.file)”, usually it is bundle No 25 , then go to crx-quickstart/launchpad/felix/bundle25/data. There are two files sitting in data which are hmac and master. Copy the files and replace them with the files sitting in publishing servers under the same path.
2. Restart the AEM server or you can restart the bundle Adobe Granite Crypto Support (com.adobe.granite.crypto). I always prefer restarting the server because it takes lesser time than restarting the Crypto Support Bundle ( this also do a kind of restart for all bundles and takes time).

How to validate the keys:
You can run a command in terminal “md5sum hmac” under the data folder and can help to match the key with all the servers to validate if the same key exists for all the servers.
Note: Initially to validate the keys, I was trying to generate the encrypted code from author and publisher and trying to match them, to validate if they are sharing the same hmac and master files But when you enter the same text on an AEM server and try to generate the encrypted code again and again, the server generates the different encryption code in every attempt. So you need not worry about it, encrypt the plain text once and put in the configurations. AEM will take care of decryption part.

When you put the encrypted key in the OSGI configuration, the encrypted key is always having curly brackets in start and end.
So if you put a config like :

You won’t be able to deploy configuration because curly brackets are always used to mention data type in OSGI Config like {boolean} true,so always mention the data type of config for encrypted keys.

Hope it will help you guys !!
Thanks and Happy Learning.

Thursday, December 12, 2019

AEM Logs in Detail Part-2

Hi everyone,

It’s been quite a long time since I published Part-1 for AEM Logs in Detail.
In the previous blog,I have already discussed all the logs provided by AEM.

But AEM provided logs are not sufficient for us sometimes. We want separate
logs for our application, so that it will be easy to debug our code.So In the blog we will discuss how to create custom loggers in AEM.

2. Go to Apache Sling Logging Logger Configuration.
3. Click on + to Add a new configuration.logging logger.PNG
  • Log level: The log level defines which type of logs you want to have in your custom log file for ex: trace,debug,info,warn,error.
  • Log File:Here you can identify the name of the log file,which needs to be created under the logs folder.
  • Message Pattern:The java.util.MessageFormat pattern to use for formatting log messages with the root logger. This is a java.util.MessageFormat pattern supporting up to six arguments:
    • {0} The timestamp of type java.util.Date,
    • {1} the log marker,
    • {2} the name of the current thread,
    • {3} the name of the logger,
    • {4} the log level and
    • {5} the actual log message.

    If the log call includes a Throwable, the stacktrace is just appended to the message regardless of the pattern.
    The Pattern can be like this: {0,date,dd.MM.yyyy HH:mm:ss.SSS} *{4}* {2} {3} {5}
  • Logger: Here we define the package name of the application,for which we want to print the logs.You can add multiple packages also.
  • Additivity: If set to false then logs from these loggers would not be sent to any appender attached higher in the hierarchy.
Let's suppose we have one logging configuration for package “com.sgaem.* “and we have created one more logger for “com.sgaem.servlet.TestServlet”, so by default the TestServlet loggers will not get printed in com.sgaem.* logger file but if you enable the additivity then the loggers will go in both log files
4.Go to Apache Sling Logging Writer Configuration.
5.Click on + to Add a new configuration.
  • Log File: Here you define the log file Name for which you want to write a logging writer.
  • Number of Log Files:Here you can define how many logs file you want to maintain for the specific Log File defined above.
  • Log File Threshold: Defines how the log file is rotated (by schedule or by size) and when to rotate.Meaning you can define if you want to rotate the log file on daily,weekly or monthly basis or on the basis of size.

Log File Rotation

Log files can grow rather quickly and fill up available disk space. To cope with this growth log files may be rotated in two ways: At specific times or when the log file reaches a configurable size. The first method is called Scheduled Rotation and is used by specifying a SimpleDateFormat pattern as the log file "size". The second method is called Size Rotation and is used by setting a maximum file size as the log file size.

Scheduled Rotation:The rolling schedule is specified by setting the property to a java.text.SimpleDateFormat pattern. It is possible to specify monthly, weekly, half-daily, daily, hourly, or minutely rollover schedules.Check this section to see available Scheduled Rotation. Do not use the colon ":" character anywhere in the pattern option. The text before the colon is interpreted as the protocol specification of a URL which is probably not what you want.

Size Rotation:Log file rotation by size is specified by setting the property to a plain number or a number plus a size multiplier. The size multiplier may be any of K, KB, M, MB, G, or GB where the case is ignored and the meaning is probably obvious.

Important to Know:

Apache Sling Logging logger Configuration is self sufficient to print the log then the question can come in your mind, what is the need of Apache Sling Logging Writer Configuration.

There is one more configuration in AEM, which is Apache Sling Logging Configuration which can be considered a global configuration for all log files.Here you define a few things like Number of Log Files,Log File Threshold,Message Pattern etc.
If you don’t override your values in your application related Logging Logger and Writer Configuration, it will take the value from Global.So if you don't define writer configuration it will take Number of Log Files and Threshold Message from global configuration.

Conclusion: if you really need any change in the two properties(Number of log files and Threshold Message) defined in the logging Writer then only create a writer configuration else no need.

There are two ways to see the log files in AEM.

1.Go to the felix console ->Sling->Log Support, and search for your log file. You can directly open the log file from here.

2. The logs files also gets created under crx-quickstart/logs. You can open your log files and see the logs.

Demonstration Video of Custom Logger in AEM:
Hope it will help you guys !!
Thanks and Happy Learning.