Excellent article: http://robbincremers.me/2011/12/27/wcf-transport-security-and-client-certificate-authentication-with-self-signed-certificates/
Monday 26 November 2012
Monday 19 November 2012
How to mitigate framesniffing with the X-Frame-Options header?
Understanding the Security Issue:
Imagine you have a page on your website, mypage1.aspx. This page can be hosted in an iframe and be shown on any pages and under any external domains and by anyone.
The problem is that when a page is hosted in an iframe, the parent page can steal the data which is communicated on the iframe page which means a decent attacker can benefit from this vulnerability.
Solution:
One possible solution to prevent these kind of security issues (doesn't work for old browsers) is to configure your IIS so that it only allows a page only being iframed in the domains you trust and prevent all other domains.
To restrict all external domains:
Put the below Field/Value pairs in the HTTPHeaders tab of your IIS Folder which contains your page:
X-Frame-Options = SAMEORIGIN
To allow an external domain:
X-Frame-Options = ALLOW-FROM http://google.com
Considerations:
- Instead of adding the X-FRAME-OPTIONS on the site root, put it on each page which requires being protected.
- For each page or folder, you can only specify one of the three main header values of "DENY, "ALLOW-FROM" or "SAMEORIGIN". You can't mix them unfortunately.
- ALLOW-FROM does support only 1 origin, not multiple.
- In IIS 6.0 you can put the header on each page needed but in IIS 7.0 it's not possible via IIS; the workaround for IIS 7.0 is via serverside code for the page.
- Not all browsers support it. IE 8+ and some other browsers. More details: http://blogs.msdn.com/b/ieinternals/archive/2010/03/30/combating-clickjacking-with-x-frame-options.aspx
Friday 9 November 2012
How to use Recaptcha?
List of IP Addresses used: http://code.google.com/p/recaptcha/wiki/FirewallsAndRecaptcha
Create a public and private key for your domain: http://www.google.com/recaptcha
Then the below code manages everything you'd need not based on the Session attempts but Application attempts:
Create a public and private key for your domain: http://www.google.com/recaptcha
Then the below code manages everything you'd need not based on the Session attempts but Application attempts:
public class RecaptchaManager { #region Local variables private static volatile RecaptchaManager _instance; private static readonly object SyncRoot = new Object(); private readonly Byte _maxNumberOfValidFailedAttempts; private readonly Byte _durationInMinutes; private readonly int _cleanUpMaxSize; private readonly string _privateKey; private readonly string _publicKey; private readonly List_result = new List (); /// /// Be careful where and how the locks are used to avoid deadlocks or inter locks. /// private readonly Object _lockObject = new object(); #endregion #region Constructors and class initialization private RecaptchaManager() { if (!Byte.TryParse(SettingHelper.Instance["Recaptcha.ValidFailedAttempts.MaxNumber"], out _maxNumberOfValidFailedAttempts)) { throw new ApplicationException("Invalid or non-existent config key: Recaptcha.ValidFailedAttempts.MaxNumber"); } if (!Byte.TryParse(SettingHelper.Instance["Recaptcha.ValidFailedAttempts.DurationInMinutes"], out _durationInMinutes)) { throw new ApplicationException("Invalid or non-existent config key: Recaptcha.ValidFailedAttempts.DurationInMinutes"); } if (!int.TryParse(SettingHelper.Instance["Recaptcha.CleanUp.MaxSize"], out _cleanUpMaxSize)) { throw new ApplicationException("Invalid or non-existent config key: Recaptcha.CleanUp.MaxSize"); } // private key this._privateKey = SettingHelper.Instance["Recaptcha.PrivateKey"]; if (string.IsNullOrWhiteSpace(this._privateKey)) { throw new ApplicationException("Invalid or non-existent config key: Recaptcha.PrivateKey"); } this._publicKey = SettingHelper.Instance["Recaptcha.PublicKey"]; if (string.IsNullOrWhiteSpace(this._publicKey)) { throw new ApplicationException("Invalid or non-existent config key: Recaptcha.PublicKey"); } } #endregion #region Properties public static RecaptchaManager Instance { get { if (_instance == null) { lock (SyncRoot) { if (_instance == null) _instance = new RecaptchaManager(); } } return _instance; } } public string PublicKey { get { return this._publicKey; } } #endregion #region public Methods public void AddFailedLoginAttempt() { // we may want to customize these addFailedLoginOrRegistrationAttempt(); } public void AddFailedRegistrationAttempt() { // we may want to customize these addFailedLoginOrRegistrationAttempt(); } public bool ShouldRequireRecaptcha() { return getNumberOfFailedAttemptsDuringThePeriod() > this._maxNumberOfValidFailedAttempts; } public bool IsRecaptchaAvailableOnPage() { // if this field exists then the Recaptcha is available string challengeValue = Utils.GetStringForm("recaptcha_challenge_field", null); return challengeValue != null; } public bool IsInputValueVerified() { string challengeValue = Utils.GetStringForm("recaptcha_challenge_field", null); string responseValue = Utils.GetStringForm("recaptcha_response_field", null); bool result = false; try { var captchaValidtor = new RecaptchaValidator() { // put it in web.config PrivateKey = this._privateKey, RemoteIP = HttpContext.Current.Request.UserHostAddress, Challenge = challengeValue, Response = responseValue }; result = captchaValidtor.Validate().IsValid; } catch { } return result; } #endregion #region Private functions private void addFailedLoginOrRegistrationAttempt() { lock (this._lockObject) { if (this._result.Count > this._cleanUpMaxSize) { this.removeOldData(); } this._result.Add(DateTime.Now); } } ////// Removes the old data. /// private void removeOldData() { DateTime startDateTime = getStartDateTime(); this._result.RemoveAll(item => item < startDateTime); } private int getNumberOfFailedAttemptsDuringThePeriod() { DateTime startDateTime = getStartDateTime(); lock (this._lockObject) { return this._result.Count(failedAttemp => failedAttemp > startDateTime); } } private DateTime getStartDateTime() { return DateTime.Now.AddMinutes(-this._durationInMinutes); } #endregion }
Subscribe to:
Posts (Atom)